diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/404.html b/404.html new file mode 100644 index 00000000000..067dc99ea74 --- /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 00000000000..12aae904168 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +operator.docs.scylladb.com \ No newline at end of file diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000000..30fee9d0f76 --- /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 00000000000..92fad4b5c0b --- /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 00000000000..54b3c463811 --- /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 00000000000..f1916ec7d1b --- /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 00000000000..2ea7ff3e217 --- /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 00000000000..dbe1aaad79c --- /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 00000000000..65eb0a55363 --- /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/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000000..eb19f698afc --- /dev/null +++ b/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_static/design-tabs.js b/_static/design-tabs.js new file mode 100644 index 00000000000..36b38cf0d91 --- /dev/null +++ b/_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000000..d06a71d7518 --- /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 00000000000..7e4c114f212 --- /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 00000000000..a858a410e4f 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 00000000000..f8520d5b3e4 --- /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 00000000000..f30770c7edd 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 00000000000..aae1708f26f 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 00000000000..6c7484f082f 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 00000000000..5448c7f007b --- /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 00000000000..09107d9520a --- /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 00000000000..1b1fcc83e30 --- /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 00000000000..7c2b4ebae0d --- /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 00000000000..7e93612026b --- /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 00000000000..67ebbc2f38c --- /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 00000000000..e1ce2c1d784 --- /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 00000000000..f4096cbf111 --- /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 00000000000..2a7c6ea0b74 --- /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 00000000000..3afa25c4812 --- /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 00000000000..44eb829cdcb --- /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 00000000000..875e4216707 --- /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 00000000000..8c924698089 --- /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 00000000000..d1162b73e73 --- /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 00000000000..a9069bb6e5c --- /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 00000000000..cfb2318daef --- /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 00000000000..49d809a5df4 --- /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 00000000000..9df3145dd21 --- /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 00000000000..ee804197a0b --- /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 00000000000..5501492f3e0 --- /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 00000000000..97be900b501 --- /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 00000000000..ee1ac26283d --- /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 00000000000..ba5f2118644 --- /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 00000000000..a7eb4b77a42 --- /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 00000000000..38065653675 --- /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 00000000000..37a709f7a8f --- /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 00000000000..702500be409 --- /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 00000000000..e8329c2afee --- /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 00000000000..f0b9c25419c --- /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 00000000000..906e87279c2 --- /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 00000000000..1ef0920d49e --- /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 00000000000..884451270d2 --- /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 00000000000..3094127decf --- /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 00000000000..dcb5916c264 --- /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 00000000000..0e6192a352c --- /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 00000000000..02b4e425beb --- /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 00000000000..e34eb4504f7 --- /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 00000000000..97fa3a0e213 --- /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 00000000000..80b3787f668 --- /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 00000000000..40a3fd5f6f1 --- /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 00000000000..a952b59937d --- /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 00000000000..5b8d47eb157 --- /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 00000000000..60ebab37953 --- /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 00000000000..98c2ea7d5bf --- /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 00000000000..bb7d8d3ea86 --- /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 00000000000..515c1528a2a --- /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 00000000000..d0146fc4972 --- /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 00000000000..5757435085a --- /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 00000000000..74b01db1684 --- /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 00000000000..80c490c7b01 --- /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 00000000000..6e3ab08e792 --- /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 00000000000..c8cbf67c8cf --- /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 00000000000..81aae93eef6 --- /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 00000000000..fc164ea1e77 --- /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 00000000000..bebe9b82742 --- /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 00000000000..4b900bd0c0a --- /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 00000000000..a4228b34e86 --- /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 00000000000..df42b5522ba --- /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 00000000000..2fe54efdbc3 --- /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 00000000000..3e7bcd6d905 --- /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 00000000000..226c44d853c --- /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 00000000000..bf7aa6af840 --- /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 00000000000..08b95a88eda --- /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 00000000000..e8ae088106f --- /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 00000000000..f7547ab9599 --- /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 00000000000..47e56cddcf7 --- /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 00000000000..e4b1d40331b --- /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 00000000000..5e9f5cd4270 --- /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 00000000000..3351e51d23c --- /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 00000000000..5206e58e986 --- /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 00000000000..4fff669cb6f --- /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 00000000000..b5022d7c4dc --- /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 00000000000..769fa0889f8 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 00000000000..7c06d01674a 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 00000000000..d33fddd62f0 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 00000000000..0462f893d5f --- /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 00000000000..a6c6a26fc99 --- /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 00000000000..d0368a7027b 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 00000000000..0cdadaa2167 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 00000000000..e889f4e368e 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 00000000000..a5bce950c25 --- /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 00000000000..6012e71679b --- /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 00000000000..a1aa0b46ac1 --- /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 00000000000..f64c29e6c7c 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 00000000000..d2f645c645a 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 00000000000..0f53b26afa5 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 00000000000..630f2d90942 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 00000000000..c87abe684d5 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 00000000000..ba52cd223db 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 00000000000..cef08c8654a 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 00000000000..75cccbfdf12 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 00000000000..6f10405f218 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 00000000000..e368cae169c 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 00000000000..74ad6695005 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 00000000000..6ba9ed937c9 --- /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 00000000000..48bec7dde32 --- /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 00000000000..956d1dd0e22 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 00000000000..7ee2b043384 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 00000000000..3b2dc8f1a2c 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 00000000000..299e9cb9955 --- /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 00000000000..655a450b2a4 --- /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 00000000000..b28dc857ccf 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 00000000000..09342ac6875 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 00000000000..9b4c613e702 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 00000000000..96dc785298b 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 00000000000..f88598e05ad 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 00000000000..6f0ca146c0d 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 00000000000..b3d0621193f 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 00000000000..b070bb022cb 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 00000000000..6a8b16a6b4e 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 00000000000..f3b8b2984f6 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 00000000000..b38a6fbbe04 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 00000000000..954bf13bc29 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 00000000000..d35a13d380d 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 00000000000..30ea1d901e1 --- /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 00000000000..190a41642ef --- /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 Operator. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      scylla.scylladb.com

      + +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/api-reference/groups/scylla.scylladb.com/nodeconfigs.html b/master/api-reference/groups/scylla.scylladb.com/nodeconfigs.html new file mode 100644 index 00000000000..478ea16c9ec --- /dev/null +++ b/master/api-reference/groups/scylla.scylladb.com/nodeconfigs.html @@ -0,0 +1,2784 @@ + + + + + + + + + + + + + NodeConfig (scylla.scylladb.com/v1alpha1) | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      NodeConfig (scylla.scylladb.com/v1alpha1)

      +
      +
      APIVersion: scylla.scylladb.com/v1alpha1
      +
      Kind: NodeConfig
      +
      PluralName: nodeconfigs
      +
      SingularName: nodeconfig
      +
      Scope: Cluster
      +
      ListKind: NodeConfigList
      +
      Served: true
      +
      Storage: true
      +
      +
      +

      Description

      +
      +
      +

      Specification

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

      Property

      Type

      Description

      apiVersion

      string

      APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

      kind

      string

      Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

      metadata

      object

      spec

      object

      status

      object

      +
      +

      .metadata

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      disableOptimizations

      boolean

      disableOptimizations controls if nodes matching placement requirements are going to be optimized. Turning off optimizations on already optimized Nodes does not revert changes.

      localDiskSetup

      object

      localDiskSetup contains options of automatic local disk setup.

      placement

      object

      placement contains scheduling rules for NodeConfig Pods.

      +
      +
      +
      +

      .spec.localDiskSetup

      +
      +

      Description

      +

      localDiskSetup contains options of automatic local disk setup.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      filesystems

      array (object)

      filesystems is a list of filesystem configurations.

      mounts

      array (object)

      mounts is a list of mount configuration.

      raids

      array (object)

      raids is a list of raid configurations.

      +
      +
      +
      +

      .spec.localDiskSetup.filesystems[]

      +
      +

      Description

      +

      FilesystemConfiguration specifies filesystem configuration options.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      device

      string

      device is a path to the device where the desired filesystem should be created.

      type

      string

      type is a desired filesystem type.

      +
      +
      +
      +

      .spec.localDiskSetup.mounts[]

      +
      +

      Description

      +

      MountConfiguration specifies mount configuration options.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      device

      string

      device is path to a device that should be mounted.

      fsType

      string

      fsType specifies the filesystem on the device.

      mountPoint

      string

      mountPoint is a path where the device should be mounted at.

      unsupportedOptions

      array (string)

      unsupportedOptions is a list of mount options used during device mounting. unsupported in this field name means that we won’t support all the available options passed down using this field.

      +
      +
      +
      +

      .spec.localDiskSetup.raids[]

      +
      +

      Description

      +

      RAIDConfiguration is a configuration of a raid array.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      RAID0

      object

      RAID0 specifies RAID0 options.

      name

      string

      name specifies the name of the raid device to be created under in /dev/md/.

      type

      string

      type is a type of raid array.

      +
      +
      +
      +

      .spec.localDiskSetup.raids[].RAID0

      +
      +

      Description

      +

      RAID0 specifies RAID0 options.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      devices

      object

      devices defines which devices constitute the raid array.

      +
      +
      +
      +

      .spec.localDiskSetup.raids[].RAID0.devices

      +
      +

      Description

      +

      devices defines which devices constitute the raid array.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      modelRegex

      string

      modelRegex is a regular expression filtering devices by their model name.

      nameRegex

      string

      nameRegex is a regular expression filtering devices by their name.

      +
      +
      +
      +

      .spec.placement

      +
      +

      Description

      +

      placement contains scheduling rules for NodeConfig Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      affinity

      object

      affinity is a group of affinity scheduling rules for NodeConfig Pods.

      nodeSelector

      object

      nodeSelector is a selector which must be true for the NodeConfig Pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node.

      tolerations

      array (object)

      tolerations is a group of tolerations NodeConfig Pods are going to have.

      +
      +
      +
      +

      .spec.placement.affinity

      +
      +

      Description

      +

      affinity is a group of affinity scheduling rules for NodeConfig Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      nodeAffinity

      object

      Describes node affinity scheduling rules for the pod.

      podAffinity

      object

      Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).

      podAntiAffinity

      object

      Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).

      +
      +
      +
      +

      .spec.placement.affinity.nodeAffinity

      +
      +

      Description

      +

      Describes node affinity scheduling rules for the pod.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      object

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

      +
      +
      +
      +

      .spec.placement.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it’s a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preference

      object

      A node selector term, associated with the corresponding weight.

      weight

      integer

      Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.placement.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference

      +
      +

      Description

      +

      A node selector term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      A list of node selector requirements by node’s labels.

      matchFields

      array (object)

      A list of node selector requirements by node’s fields.

      +
      +
      +
      +

      .spec.placement.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchExpressions[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchFields[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution

      +
      +

      Description

      +

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      nodeSelectorTerms

      array (object)

      Required. A list of node selector terms. The terms are ORed.

      +
      +
      +
      +

      .spec.placement.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[]

      +
      +

      Description

      +

      A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      A list of node selector requirements by node’s labels.

      matchFields

      array (object)

      A list of node selector requirements by node’s fields.

      +
      +
      +
      +

      .spec.placement.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchExpressions[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchFields[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity

      +
      +

      Description

      +

      Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      array (object)

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podAffinityTerm

      object

      Required. A pod affinity term, associated with the corresponding weight.

      weight

      integer

      weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm

      +
      +

      Description

      +

      Required. A pod affinity term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity

      +
      +

      Description

      +

      Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      array (object)

      If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podAffinityTerm

      object

      Required. A pod affinity term, associated with the corresponding weight.

      weight

      integer

      weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm

      +
      +

      Description

      +

      Required. A pod affinity term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.placement.nodeSelector

      +
      +

      Description

      +

      nodeSelector is a selector which must be true for the NodeConfig Pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.placement.tolerations[]

      +
      +

      Description

      +

      The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      effect

      string

      Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.

      key

      string

      Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys.

      operator

      string

      Operator represents a key’s relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.

      tolerationSeconds

      integer

      TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.

      value

      string

      Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.

      +
      +
      +
      +

      .status

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      conditions

      array (object)

      conditions represents the latest available observations of current state.

      nodeStatuses

      array (object)

      nodeStatuses hold the status for each tuned node.

      observedGeneration

      integer

      observedGeneration indicates the most recent generation observed by the controller.

      +
      +
      +
      +

      .status.conditions[]

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      lastTransitionTime

      string

      lastTransitionTime is last time the condition transitioned from one status to another.

      message

      string

      message is a human-readable message indicating details about the transition.

      observedGeneration

      integer

      observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

      reason

      string

      reason is the reason for condition’s last transition.

      status

      string

      status represents the state of the condition, one of True, False, or Unknown.

      type

      string

      type is the type of the NodeConfig condition.

      +
      +
      +
      +

      .status.nodeStatuses[]

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      tunedContainers

      array (string)

      tunedNode

      boolean

      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/api-reference/groups/scylla.scylladb.com/scyllaclusters.html b/master/api-reference/groups/scylla.scylladb.com/scyllaclusters.html new file mode 100644 index 00000000000..1bb8ddf072f --- /dev/null +++ b/master/api-reference/groups/scylla.scylladb.com/scyllaclusters.html @@ -0,0 +1,7016 @@ + + + + + + + + + + + + + ScyllaCluster (scylla.scylladb.com/v1) | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      ScyllaCluster (scylla.scylladb.com/v1)

      +
      +
      APIVersion: scylla.scylladb.com/v1
      +
      Kind: ScyllaCluster
      +
      PluralName: scyllaclusters
      +
      SingularName: scyllacluster
      +
      Scope: Namespaced
      +
      ListKind: ScyllaClusterList
      +
      Served: true
      +
      Storage: true
      +
      +
      +

      Description

      +

      ScyllaCluster defines a Scylla cluster.

      +
      +
      +

      Specification

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

      Property

      Type

      Description

      apiVersion

      string

      APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

      kind

      string

      Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

      metadata

      object

      spec

      object

      spec defines the desired state of this scylla cluster.

      status

      object

      status is the current status of this scylla cluster.

      +
      +

      .metadata

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec

      +
      +

      Description

      +

      spec defines the desired state of this scylla cluster.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      agentRepository

      string

      agentRepository is the repository to pull the agent image from.

      agentVersion

      string

      agentVersion indicates the version of Scylla Manager Agent to use.

      alternator

      object

      alternator designates this cluster an Alternator cluster.

      automaticOrphanedNodeCleanup

      boolean

      automaticOrphanedNodeCleanup controls if automatic orphan node cleanup should be performed.

      backups

      array (object)

      backups specifies backup tasks in Scylla Manager. When Scylla Manager is not installed, these will be ignored.

      cpuset

      boolean

      cpuset determines if the cluster will use cpu-pinning for max performance.

      datacenter

      object

      datacenter holds a specification of a datacenter.

      developerMode

      boolean

      developerMode determines if the cluster runs in developer-mode.

      dnsDomains

      array (string)

      dnsDomains is a list of DNS domains this cluster is reachable by. These domains are used when setting up the infrastructure, like certificates. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      exposeOptions

      object

      exposeOptions specifies options for exposing ScyllaCluster services. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      externalSeeds

      array (string)

      externalSeeds specifies the external seeds to propagate to ScyllaDB binary on startup as “seeds” parameter of seed-provider.

      forceRedeploymentReason

      string

      forceRedeploymentReason can be used to force a rolling update of all racks by providing a unique string.

      genericUpgrade

      object

      genericUpgrade allows to configure behavior of generic upgrade logic.

      imagePullSecrets

      array (object)

      imagePullSecrets is an optional list of references to secrets in the same namespace used for pulling Scylla and Agent images.

      network

      object

      network holds the networking config.

      repairs

      array (object)

      repairs specify repair tasks in Scylla Manager. When Scylla Manager is not installed, these will be ignored.

      repository

      string

      repository is the image repository to pull the Scylla image from.

      scyllaArgs

      string

      scyllaArgs will be appended to Scylla binary during startup. This is supported from 4.2.0 Scylla version.

      sysctls

      array (string)

      sysctls holds the sysctl properties to be applied during initialization given as a list of key=value pairs. Example: fs.aio-max-nr=232323

      version

      string

      version is a version tag of Scylla to use.

      +
      +
      +
      +

      .spec.alternator

      +
      +

      Description

      +

      alternator designates this cluster an Alternator cluster.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      port

      integer

      port is the port number used to bind the Alternator API.

      writeIsolation

      string

      writeIsolation indicates the isolation level.

      +
      +
      +
      +

      .spec.backups[]

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      dc

      array (string)

      dc is a list of datacenter glob patterns, e.g. ‘dc1,!otherdc*’ used to specify the DCs to include or exclude from backup.

      interval

      string

      interval represents a task schedule interval e.g. 3d2h10m, valid units are d, h, m, s.

      keyspace

      array (string)

      keyspace is a list of keyspace/tables glob patterns, e.g. ‘keyspace,!keyspace.table_prefix_*’ used to include or exclude keyspaces from repair.

      location

      array (string)

      location is a list of backup locations in the format [<dc>:]<provider>:<name> ex. s3:my-bucket. The <dc>: part is optional and is only needed when different datacenters are being used to upload data to different locations. <name> must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. The only supported storage <provider> at the moment are s3 and gcs.

      name

      string

      name is a unique name of a task.

      numRetries

      integer

      numRetries indicates how many times a scheduled task will be retried before failing.

      rateLimit

      array (string)

      rateLimit is a list of megabytes (MiB) per second rate limits expressed in the format [<dc>:]<limit>. The <dc>: part is optional and only needed when different datacenters need different upload limits. Set to 0 for no limit (default 100).

      retention

      integer

      retention is the number of backups which are to be stored.

      snapshotParallel

      array (string)

      snapshotParallel is a list of snapshot parallelism limits in the format [<dc>:]<limit>. The <dc>: part is optional and allows for specifying different limits in selected datacenters. If The <dc>: part is not set, the limit is global (e.g. ‘dc1:2,5’) the runs are parallel in n nodes (2 in dc1) and n nodes in all the other datacenters.

      startDate

      string

      startDate specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, valid units are d, h, m, s.

      uploadParallel

      array (string)

      uploadParallel is a list of upload parallelism limits in the format [<dc>:]<limit>. The <dc>: part is optional and allows for specifying different limits in selected datacenters. If The <dc>: part is not set the limit is global (e.g. ‘dc1:2,5’) the runs are parallel in n nodes (2 in dc1) and n nodes in all the other datacenters.

      +
      +
      +
      +

      .spec.datacenter

      +
      +

      Description

      +

      datacenter holds a specification of a datacenter.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      name is the name of the scylla datacenter. Used in the cassandra-rackdc.properties file.

      racks

      array (object)

      racks specify the racks in the datacenter.

      +
      +
      +
      +

      .spec.datacenter.racks[]

      +
      +

      Description

      +

      RackSpec is the desired state for a Scylla Rack.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      agentResources

      object

      agentResources specify the resources for the Agent container.

      agentVolumeMounts

      array (object)

      AgentVolumeMounts to be added to Agent container.

      members

      integer

      members is the number of Scylla instances in this rack.

      name

      string

      name is the name of the Scylla Rack. Used in the cassandra-rackdc.properties file.

      placement

      object

      placement describes restrictions for the nodes Scylla is scheduled on.

      resources

      object

      resources the Scylla container will use.

      scyllaAgentConfig

      string

      Scylla config map name to customize scylla manager agent

      scyllaConfig

      string

      Scylla config map name to customize scylla.yaml

      storage

      object

      storage describes the underlying storage that Scylla will consume.

      volumeMounts

      array (object)

      VolumeMounts to be added to Scylla container.

      volumes

      array (object)

      Volumes added to Scylla Pod.

      +
      +
      +
      +

      .spec.datacenter.racks[].agentResources

      +
      +

      Description

      +

      agentResources specify the resources for the Agent container.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      claims

      array (object)

      +
      Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.

      This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. +This field is immutable. It can only be set for containers.

      +
      +
      +

      limits

      object

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      requests

      object

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +
      +

      .spec.datacenter.racks[].agentResources.claims[]

      +
      +

      Description

      +

      ResourceClaim references one entry in PodSpec.ResourceClaims.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.

      +
      +
      +
      +

      .spec.datacenter.racks[].agentResources.limits

      +
      +

      Description

      +

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].agentResources.requests

      +
      +

      Description

      +

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].agentVolumeMounts[]

      +
      +

      Description

      +

      VolumeMount describes a mounting of a Volume within a container.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      mountPath

      string

      Path within the container at which the volume should be mounted. Must not contain ‘:’.

      mountPropagation

      string

      mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10.

      name

      string

      This must match the Name of a Volume.

      readOnly

      boolean

      Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.

      subPath

      string

      Path within the volume from which the container’s volume should be mounted. Defaults to “” (volume’s root).

      subPathExpr

      string

      Expanded path within the volume from which the container’s volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container’s environment. Defaults to “” (volume’s root). SubPathExpr and SubPath are mutually exclusive.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement

      +
      +

      Description

      +

      placement describes restrictions for the nodes Scylla is scheduled on.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      nodeAffinity

      object

      nodeAffinity describes node affinity scheduling rules for the pod.

      podAffinity

      object

      podAffinity describes pod affinity scheduling rules.

      podAntiAffinity

      object

      podAntiAffinity describes pod anti-affinity scheduling rules.

      tolerations

      array (object)

      tolerations allow the pod to tolerate any taint that matches the triple <key,value,effect> using the matching operator.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.nodeAffinity

      +
      +

      Description

      +

      nodeAffinity describes node affinity scheduling rules for the pod.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      object

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it’s a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preference

      object

      A node selector term, associated with the corresponding weight.

      weight

      integer

      Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference

      +
      +

      Description

      +

      A node selector term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      A list of node selector requirements by node’s labels.

      matchFields

      array (object)

      A list of node selector requirements by node’s fields.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchExpressions[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchFields[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution

      +
      +

      Description

      +

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      nodeSelectorTerms

      array (object)

      Required. A list of node selector terms. The terms are ORed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[]

      +
      +

      Description

      +

      A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      A list of node selector requirements by node’s labels.

      matchFields

      array (object)

      A list of node selector requirements by node’s fields.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchExpressions[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchFields[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity

      +
      +

      Description

      +

      podAffinity describes pod affinity scheduling rules.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      array (object)

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podAffinityTerm

      object

      Required. A pod affinity term, associated with the corresponding weight.

      weight

      integer

      weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm

      +
      +

      Description

      +

      Required. A pod affinity term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity

      +
      +

      Description

      +

      podAntiAffinity describes pod anti-affinity scheduling rules.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      array (object)

      If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podAffinityTerm

      object

      Required. A pod affinity term, associated with the corresponding weight.

      weight

      integer

      weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm

      +
      +

      Description

      +

      Required. A pod affinity term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].placement.tolerations[]

      +
      +

      Description

      +

      The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      effect

      string

      Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.

      key

      string

      Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys.

      operator

      string

      Operator represents a key’s relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.

      tolerationSeconds

      integer

      TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.

      value

      string

      Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.

      +
      +
      +
      +

      .spec.datacenter.racks[].resources

      +
      +

      Description

      +

      resources the Scylla container will use.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      claims

      array (object)

      +
      Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.

      This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. +This field is immutable. It can only be set for containers.

      +
      +
      +

      limits

      object

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      requests

      object

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +
      +

      .spec.datacenter.racks[].resources.claims[]

      +
      +

      Description

      +

      ResourceClaim references one entry in PodSpec.ResourceClaims.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.

      +
      +
      +
      +

      .spec.datacenter.racks[].resources.limits

      +
      +

      Description

      +

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].resources.requests

      +
      +

      Description

      +

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].storage

      +
      +

      Description

      +

      storage describes the underlying storage that Scylla will consume.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      capacity

      string

      capacity describes the requested size of each persistent volume.

      storageClassName

      string

      storageClassName is the name of a storageClass to request.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumeMounts[]

      +
      +

      Description

      +

      VolumeMount describes a mounting of a Volume within a container.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      mountPath

      string

      Path within the container at which the volume should be mounted. Must not contain ‘:’.

      mountPropagation

      string

      mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10.

      name

      string

      This must match the Name of a Volume.

      readOnly

      boolean

      Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.

      subPath

      string

      Path within the volume from which the container’s volume should be mounted. Defaults to “” (volume’s root).

      subPathExpr

      string

      Expanded path within the volume from which the container’s volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container’s environment. Defaults to “” (volume’s root). SubPathExpr and SubPath are mutually exclusive.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[]

      +
      +

      Description

      +

      Volume represents a named volume in a pod that may be accessed by any container in the pod.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      awsElasticBlockStore

      object

      awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet’s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

      azureDisk

      object

      azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.

      azureFile

      object

      azureFile represents an Azure File Service mount on the host and bind mount to the pod.

      cephfs

      object

      cephFS represents a Ceph FS mount on the host that shares a pod’s lifetime

      cinder

      object

      cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

      configMap

      object

      configMap represents a configMap that should populate this volume

      csi

      object

      csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature).

      downwardAPI

      object

      downwardAPI represents downward API about the pod that should populate this volume

      emptyDir

      object

      emptyDir represents a temporary directory that shares a pod’s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

      ephemeral

      object

      +
      ephemeral represents a volume that is handled by a cluster storage driver. The volume’s lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed.

      Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). +Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. +Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. +A pod can use both types of ephemeral volumes and persistent volumes at the same time.

      +
      +
      +

      fc

      object

      fc represents a Fibre Channel resource that is attached to a kubelet’s host machine and then exposed to the pod.

      flexVolume

      object

      flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin.

      flocker

      object

      flocker represents a Flocker volume attached to a kubelet’s host machine. This depends on the Flocker control service being running

      gcePersistentDisk

      object

      gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet’s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

      gitRepo

      object

      gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod’s container.

      glusterfs

      object

      glusterfs represents a Glusterfs mount on the host that shares a pod’s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md

      hostPath

      object

      hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath — TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not mount host directories as read/write.

      iscsi

      object

      iscsi represents an ISCSI Disk resource that is attached to a kubelet’s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md

      name

      string

      name of the volume. Must be a DNS_LABEL and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

      nfs

      object

      nfs represents an NFS mount on the host that shares a pod’s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

      persistentVolumeClaim

      object

      persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

      photonPersistentDisk

      object

      photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine

      portworxVolume

      object

      portworxVolume represents a portworx volume attached and mounted on kubelets host machine

      projected

      object

      projected items for all in one resources secrets, configmaps, and downward API

      quobyte

      object

      quobyte represents a Quobyte mount on the host that shares a pod’s lifetime

      rbd

      object

      rbd represents a Rados Block Device mount on the host that shares a pod’s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md

      scaleIO

      object

      scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.

      secret

      object

      secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret

      storageos

      object

      storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.

      vsphereVolume

      object

      vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].awsElasticBlockStore

      +
      +

      Description

      +

      awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet’s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine

      partition

      integer

      partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as “1”. Similarly, the volume partition for /dev/sda is “0” (or you can leave the property empty).

      readOnly

      boolean

      readOnly value true will force the readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

      volumeID

      string

      volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].azureDisk

      +
      +

      Description

      +

      azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      cachingMode

      string

      cachingMode is the Host Caching mode: None, Read Only, Read Write.

      diskName

      string

      diskName is the Name of the data disk in the blob storage

      diskURI

      string

      diskURI is the URI of data disk in the blob storage

      fsType

      string

      fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified.

      kind

      string

      kind expected values are Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared

      readOnly

      boolean

      readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].azureFile

      +
      +

      Description

      +

      azureFile represents an Azure File Service mount on the host and bind mount to the pod.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      readOnly

      boolean

      readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

      secretName

      string

      secretName is the name of secret that contains Azure Storage Account Name and Key

      shareName

      string

      shareName is the azure share Name

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].cephfs

      +
      +

      Description

      +

      cephFS represents a Ceph FS mount on the host that shares a pod’s lifetime

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      monitors

      array (string)

      monitors is Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

      path

      string

      path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /

      readOnly

      boolean

      readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

      secretFile

      string

      secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

      secretRef

      object

      secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

      user

      string

      user is optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].cephfs.secretRef

      +
      +

      Description

      +

      secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].cinder

      +
      +

      Description

      +

      cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

      readOnly

      boolean

      readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

      secretRef

      object

      secretRef is optional: points to a secret object containing parameters used to connect to OpenStack.

      volumeID

      string

      volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].cinder.secretRef

      +
      +

      Description

      +

      secretRef is optional: points to a secret object containing parameters used to connect to OpenStack.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].configMap

      +
      +

      Description

      +

      configMap represents a configMap that should populate this volume

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      defaultMode

      integer

      defaultMode is optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      items

      array (object)

      items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the ‘..’ path or start with ‘..’.

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      optional

      boolean

      optional specify whether the ConfigMap or its keys must be defined

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].configMap.items[]

      +
      +

      Description

      +

      Maps a string key to a path within a volume.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the key to project.

      mode

      integer

      mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      path

      string

      path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element ‘..’. May not start with the string ‘..’.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].csi

      +
      +

      Description

      +

      csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature).

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      driver

      string

      driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster.

      fsType

      string

      fsType to mount. Ex. “ext4”, “xfs”, “ntfs”. If not provided, the empty value is passed to the associated CSI driver which will determine the default filesystem to apply.

      nodePublishSecretRef

      object

      nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secret references are passed.

      readOnly

      boolean

      readOnly specifies a read-only configuration for the volume. Defaults to false (read/write).

      volumeAttributes

      object

      volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver’s documentation for supported values.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].csi.nodePublishSecretRef

      +
      +

      Description

      +

      nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secret references are passed.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].csi.volumeAttributes

      +
      +

      Description

      +

      volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver’s documentation for supported values.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].downwardAPI

      +
      +

      Description

      +

      downwardAPI represents downward API about the pod that should populate this volume

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      defaultMode

      integer

      Optional: mode bits to use on created files by default. Must be a Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      items

      array (object)

      Items is a list of downward API volume file

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].downwardAPI.items[]

      +
      +

      Description

      +

      DownwardAPIVolumeFile represents information to create the file containing the pod field

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fieldRef

      object

      Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.

      mode

      integer

      Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      path

      string

      Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ‘..’ path. Must be utf-8 encoded. The first item of the relative path must not start with ‘..’

      resourceFieldRef

      object

      Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].downwardAPI.items[].fieldRef

      +
      +

      Description

      +

      Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      apiVersion

      string

      Version of the schema the FieldPath is written in terms of, defaults to “v1”.

      fieldPath

      string

      Path of the field to select in the specified API version.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].downwardAPI.items[].resourceFieldRef

      +
      +

      Description

      +

      Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      containerName

      string

      Container name: required for volumes, optional for env vars

      divisor

      Specifies the output format of the exposed resources, defaults to “1”

      resource

      string

      Required: resource to select

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].emptyDir

      +
      +

      Description

      +

      emptyDir represents a temporary directory that shares a pod’s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      medium

      string

      medium represents what type of storage medium should back this directory. The default is “” which means to use the node’s default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

      sizeLimit

      sizeLimit is the total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral

      +
      +

      Description

      +
      +
      ephemeral represents a volume that is handled by a cluster storage driver. The volume’s lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed.

      Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). +Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. +Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. +A pod can use both types of ephemeral volumes and persistent volumes at the same time.

      +
      +
      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      volumeClaimTemplate

      object

      +
      Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be <pod name>-<volume name> where <volume name> is the name from the PodSpec.Volumes array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long).

      An existing PVC with that name that is not owned by the pod will not be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. +This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. +Required, must not be nil.

      +
      +
      +
      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate

      +
      +

      Description

      +
      +
      Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be <pod name>-<volume name> where <volume name> is the name from the PodSpec.Volumes array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long).

      An existing PVC with that name that is not owned by the pod will not be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. +This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. +Required, must not be nil.

      +
      +
      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      metadata

      object

      May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation.

      spec

      object

      The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.metadata

      +
      +

      Description

      +

      May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec

      +
      +

      Description

      +

      The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      accessModes

      array (string)

      accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1

      dataSource

      object

      dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.

      dataSourceRef

      object

      dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn’t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn’t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.

      resources

      object

      resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources

      selector

      object

      selector is a label query over volumes to consider for binding.

      storageClassName

      string

      storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1

      volumeAttributesClassName

      string

      volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. If specified, the CSI driver will create or update the volume with the attributes defined in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass will be applied to the claim but it’s not allowed to reset this field to empty string once it is set. If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass will be set by the persistentvolume controller if it exists. If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.

      volumeMode

      string

      volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.

      volumeName

      string

      volumeName is the binding reference to the PersistentVolume backing this claim.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.dataSource

      +
      +

      Description

      +

      dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      apiGroup

      string

      APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.

      kind

      string

      Kind is the type of resource being referenced

      name

      string

      Name is the name of resource being referenced

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.dataSourceRef

      +
      +

      Description

      +

      dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn’t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn’t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      apiGroup

      string

      APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.

      kind

      string

      Kind is the type of resource being referenced

      name

      string

      Name is the name of resource being referenced

      namespace

      string

      Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace’s owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.resources

      +
      +

      Description

      +

      resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      limits

      object

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      requests

      object

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.resources.limits

      +
      +

      Description

      +

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.resources.requests

      +
      +

      Description

      +

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.selector

      +
      +

      Description

      +

      selector is a label query over volumes to consider for binding.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.selector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.selector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].fc

      +
      +

      Description

      +

      fc represents a Fibre Channel resource that is attached to a kubelet’s host machine and then exposed to the pod.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified. TODO: how do we prevent errors in the filesystem from compromising the machine

      lun

      integer

      lun is Optional: FC target lun number

      readOnly

      boolean

      readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

      targetWWNs

      array (string)

      targetWWNs is Optional: FC target worldwide names (WWNs)

      wwids

      array (string)

      wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].flexVolume

      +
      +

      Description

      +

      flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      driver

      string

      driver is the name of the driver to use for this volume.

      fsType

      string

      fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. “ext4”, “xfs”, “ntfs”. The default filesystem depends on FlexVolume script.

      options

      object

      options is Optional: this field holds extra command options if any.

      readOnly

      boolean

      readOnly is Optional: defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

      secretRef

      object

      secretRef is Optional: secretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].flexVolume.options

      +
      +

      Description

      +

      options is Optional: this field holds extra command options if any.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].flexVolume.secretRef

      +
      +

      Description

      +

      secretRef is Optional: secretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].flocker

      +
      +

      Description

      +

      flocker represents a Flocker volume attached to a kubelet’s host machine. This depends on the Flocker control service being running

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      datasetName

      string

      datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker should be considered as deprecated

      datasetUUID

      string

      datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].gcePersistentDisk

      +
      +

      Description

      +

      gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet’s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fsType is filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine

      partition

      integer

      partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as “1”. Similarly, the volume partition for /dev/sda is “0” (or you can leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

      pdName

      string

      pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

      readOnly

      boolean

      readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].gitRepo

      +
      +

      Description

      +

      gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod’s container.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      directory

      string

      directory is the target directory name. Must not contain or start with ‘..’. If ‘.’ is supplied, the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name.

      repository

      string

      repository is the URL

      revision

      string

      revision is the commit hash for the specified revision.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].glusterfs

      +
      +

      Description

      +

      glusterfs represents a Glusterfs mount on the host that shares a pod’s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      endpoints

      string

      endpoints is the endpoint name that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

      path

      string

      path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

      readOnly

      boolean

      readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].hostPath

      +
      +

      Description

      +

      hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath — TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not mount host directories as read/write.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      path

      string

      path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath

      type

      string

      type for HostPath Volume Defaults to “” More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].iscsi

      +
      +

      Description

      +

      iscsi represents an ISCSI Disk resource that is attached to a kubelet’s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      chapAuthDiscovery

      boolean

      chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication

      chapAuthSession

      boolean

      chapAuthSession defines whether support iSCSI Session CHAP authentication

      fsType

      string

      fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine

      initiatorName

      string

      initiatorName is the custom iSCSI Initiator Name. If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface <target portal>:<volume name> will be created for the connection.

      iqn

      string

      iqn is the target iSCSI Qualified Name.

      iscsiInterface

      string

      iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to ‘default’ (tcp).

      lun

      integer

      lun represents iSCSI Target Lun number.

      portals

      array (string)

      portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).

      readOnly

      boolean

      readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false.

      secretRef

      object

      secretRef is the CHAP Secret for iSCSI target and initiator authentication

      targetPortal

      string

      targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].iscsi.secretRef

      +
      +

      Description

      +

      secretRef is the CHAP Secret for iSCSI target and initiator authentication

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].nfs

      +
      +

      Description

      +

      nfs represents an NFS mount on the host that shares a pod’s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      path

      string

      path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

      readOnly

      boolean

      readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

      server

      string

      server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].persistentVolumeClaim

      +
      +

      Description

      +

      persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      claimName

      string

      claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

      readOnly

      boolean

      readOnly Will force the ReadOnly setting in VolumeMounts. Default false.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].photonPersistentDisk

      +
      +

      Description

      +

      photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified.

      pdID

      string

      pdID is the ID that identifies Photon Controller persistent disk

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].portworxVolume

      +
      +

      Description

      +

      portworxVolume represents a portworx volume attached and mounted on kubelets host machine

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. “ext4”, “xfs”. Implicitly inferred to be “ext4” if unspecified.

      readOnly

      boolean

      readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

      volumeID

      string

      volumeID uniquely identifies a Portworx volume

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected

      +
      +

      Description

      +

      projected items for all in one resources secrets, configmaps, and downward API

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      defaultMode

      integer

      defaultMode are the mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      sources

      array (object)

      sources is the list of volume projections

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[]

      +
      +

      Description

      +

      Projection that may be projected along with other supported volume types

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      clusterTrustBundle

      object

      +
      ClusterTrustBundle allows a pod to access the .spec.trustBundle field of ClusterTrustBundle objects in an auto-updating file.

      Alpha, gated by the ClusterTrustBundleProjection feature gate. +ClusterTrustBundle objects can either be selected by name, or by the combination of signer name and a label selector. +Kubelet performs aggressive normalization of the PEM contents written into the pod filesystem. Esoteric PEM features such as inter-block comments and block headers are stripped. Certificates are deduplicated. The ordering of certificates within the file is arbitrary, and Kubelet may change the order over time.

      +
      +
      +

      configMap

      object

      configMap information about the configMap data to project

      downwardAPI

      object

      downwardAPI information about the downwardAPI data to project

      secret

      object

      secret information about the secret data to project

      serviceAccountToken

      object

      serviceAccountToken is information about the serviceAccountToken data to project

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].clusterTrustBundle

      +
      +

      Description

      +
      +
      ClusterTrustBundle allows a pod to access the .spec.trustBundle field of ClusterTrustBundle objects in an auto-updating file.

      Alpha, gated by the ClusterTrustBundleProjection feature gate. +ClusterTrustBundle objects can either be selected by name, or by the combination of signer name and a label selector. +Kubelet performs aggressive normalization of the PEM contents written into the pod filesystem. Esoteric PEM features such as inter-block comments and block headers are stripped. Certificates are deduplicated. The ordering of certificates within the file is arbitrary, and Kubelet may change the order over time.

      +
      +
      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      Select all ClusterTrustBundles that match this label selector. Only has effect if signerName is set. Mutually-exclusive with name. If unset, interpreted as “match nothing”. If set but empty, interpreted as “match everything”.

      name

      string

      Select a single ClusterTrustBundle by object name. Mutually-exclusive with signerName and labelSelector.

      optional

      boolean

      If true, don’t block pod startup if the referenced ClusterTrustBundle(s) aren’t available. If using name, then the named ClusterTrustBundle is allowed not to exist. If using signerName, then the combination of signerName and labelSelector is allowed to match zero ClusterTrustBundles.

      path

      string

      Relative path from the volume root to write the bundle.

      signerName

      string

      Select all ClusterTrustBundles that match this signer name. Mutually-exclusive with name. The contents of all selected ClusterTrustBundles will be unified and deduplicated.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].clusterTrustBundle.labelSelector

      +
      +

      Description

      +

      Select all ClusterTrustBundles that match this label selector. Only has effect if signerName is set. Mutually-exclusive with name. If unset, interpreted as “match nothing”. If set but empty, interpreted as “match everything”.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].clusterTrustBundle.labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].clusterTrustBundle.labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].configMap

      +
      +

      Description

      +

      configMap information about the configMap data to project

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      items

      array (object)

      items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the ‘..’ path or start with ‘..’.

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      optional

      boolean

      optional specify whether the ConfigMap or its keys must be defined

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].configMap.items[]

      +
      +

      Description

      +

      Maps a string key to a path within a volume.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the key to project.

      mode

      integer

      mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      path

      string

      path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element ‘..’. May not start with the string ‘..’.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].downwardAPI

      +
      +

      Description

      +

      downwardAPI information about the downwardAPI data to project

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      items

      array (object)

      Items is a list of DownwardAPIVolume file

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].downwardAPI.items[]

      +
      +

      Description

      +

      DownwardAPIVolumeFile represents information to create the file containing the pod field

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fieldRef

      object

      Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.

      mode

      integer

      Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      path

      string

      Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ‘..’ path. Must be utf-8 encoded. The first item of the relative path must not start with ‘..’

      resourceFieldRef

      object

      Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].downwardAPI.items[].fieldRef

      +
      +

      Description

      +

      Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      apiVersion

      string

      Version of the schema the FieldPath is written in terms of, defaults to “v1”.

      fieldPath

      string

      Path of the field to select in the specified API version.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].downwardAPI.items[].resourceFieldRef

      +
      +

      Description

      +

      Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      containerName

      string

      Container name: required for volumes, optional for env vars

      divisor

      Specifies the output format of the exposed resources, defaults to “1”

      resource

      string

      Required: resource to select

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].secret

      +
      +

      Description

      +

      secret information about the secret data to project

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      items

      array (object)

      items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the ‘..’ path or start with ‘..’.

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      optional

      boolean

      optional field specify whether the Secret or its key must be defined

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].secret.items[]

      +
      +

      Description

      +

      Maps a string key to a path within a volume.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the key to project.

      mode

      integer

      mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      path

      string

      path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element ‘..’. May not start with the string ‘..’.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].projected.sources[].serviceAccountToken

      +
      +

      Description

      +

      serviceAccountToken is information about the serviceAccountToken data to project

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      audience

      string

      audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise should reject the token. The audience defaults to the identifier of the apiserver.

      expirationSeconds

      integer

      expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively rotate the service account token. The kubelet will start trying to rotate the token if the token is older than 80 percent of its time to live or if the token is older than 24 hours.Defaults to 1 hour and must be at least 10 minutes.

      path

      string

      path is the path relative to the mount point of the file to project the token into.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].quobyte

      +
      +

      Description

      +

      quobyte represents a Quobyte mount on the host that shares a pod’s lifetime

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      group

      string

      group to map volume access to Default is no group

      readOnly

      boolean

      readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false.

      registry

      string

      registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes

      tenant

      string

      tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin

      user

      string

      user to map volume access to Defaults to serivceaccount user

      volume

      string

      volume is a string that references an already created Quobyte volume by name.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].rbd

      +
      +

      Description

      +

      rbd represents a Rados Block Device mount on the host that shares a pod’s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine

      image

      string

      image is the rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

      keyring

      string

      keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

      monitors

      array (string)

      monitors is a collection of Ceph monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

      pool

      string

      pool is the rados pool name. Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

      readOnly

      boolean

      readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

      secretRef

      object

      secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

      user

      string

      user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].rbd.secretRef

      +
      +

      Description

      +

      secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].scaleIO

      +
      +

      Description

      +

      scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. “ext4”, “xfs”, “ntfs”. Default is “xfs”.

      gateway

      string

      gateway is the host address of the ScaleIO API Gateway.

      protectionDomain

      string

      protectionDomain is the name of the ScaleIO Protection Domain for the configured storage.

      readOnly

      boolean

      readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

      secretRef

      object

      secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail.

      sslEnabled

      boolean

      sslEnabled Flag enable/disable SSL communication with Gateway, default false

      storageMode

      string

      storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned.

      storagePool

      string

      storagePool is the ScaleIO Storage Pool associated with the protection domain.

      system

      string

      system is the name of the storage system as configured in ScaleIO.

      volumeName

      string

      volumeName is the name of a volume already created in the ScaleIO system that is associated with this volume source.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].scaleIO.secretRef

      +
      +

      Description

      +

      secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].secret

      +
      +

      Description

      +

      secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      defaultMode

      integer

      defaultMode is Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      items

      array (object)

      items If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the ‘..’ path or start with ‘..’.

      optional

      boolean

      optional field specify whether the Secret or its keys must be defined

      secretName

      string

      secretName is the name of the secret in the pod’s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].secret.items[]

      +
      +

      Description

      +

      Maps a string key to a path within a volume.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the key to project.

      mode

      integer

      mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.

      path

      string

      path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element ‘..’. May not start with the string ‘..’.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].storageos

      +
      +

      Description

      +

      storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified.

      readOnly

      boolean

      readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.

      secretRef

      object

      secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted.

      volumeName

      string

      volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace.

      volumeNamespace

      string

      volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod’s namespace will be used. This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to “default” if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created.

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].storageos.secretRef

      +
      +

      Description

      +

      secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      +
      +
      +
      +

      .spec.datacenter.racks[].volumes[].vsphereVolume

      +
      +

      Description

      +

      vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      fsType

      string

      fsType is filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. “ext4”, “xfs”, “ntfs”. Implicitly inferred to be “ext4” if unspecified.

      storagePolicyID

      string

      storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName.

      storagePolicyName

      string

      storagePolicyName is the storage Policy Based Management (SPBM) profile name.

      volumePath

      string

      volumePath is the path that identifies vSphere volume vmdk

      +
      +
      +
      +

      .spec.exposeOptions

      +
      +

      Description

      +

      exposeOptions specifies options for exposing ScyllaCluster services. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      broadcastOptions

      object

      BroadcastOptions defines how ScyllaDB node publishes its IP address to other nodes and clients.

      cql

      object

      cql specifies expose options for CQL SSL backend. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      nodeService

      object

      nodeService controls properties of Service dedicated for each ScyllaCluster node.

      +
      +
      +
      +

      .spec.exposeOptions.broadcastOptions

      +
      +

      Description

      +

      BroadcastOptions defines how ScyllaDB node publishes its IP address to other nodes and clients.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      clients

      object

      clients specifies options related to the address that is broadcasted for communication with clients. This field controls the broadcast_rpc_address value in ScyllaDB config.

      nodes

      object

      nodes specifies options related to the address that is broadcasted for communication with other nodes. This field controls the broadcast_address value in ScyllaDB config.

      +
      +
      +
      +

      .spec.exposeOptions.broadcastOptions.clients

      +
      +

      Description

      +

      clients specifies options related to the address that is broadcasted for communication with clients. This field controls the broadcast_rpc_address value in ScyllaDB config.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podIP

      object

      podIP holds options related to Pod IP address.

      type

      string

      type of the address that is broadcasted.

      +
      +
      +
      +

      .spec.exposeOptions.broadcastOptions.clients.podIP

      +
      +

      Description

      +

      podIP holds options related to Pod IP address.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      source

      string

      sourceType specifies source of the Pod IP.

      +
      +
      +
      +

      .spec.exposeOptions.broadcastOptions.nodes

      +
      +

      Description

      +

      nodes specifies options related to the address that is broadcasted for communication with other nodes. This field controls the broadcast_address value in ScyllaDB config.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podIP

      object

      podIP holds options related to Pod IP address.

      type

      string

      type of the address that is broadcasted.

      +
      +
      +
      +

      .spec.exposeOptions.broadcastOptions.nodes.podIP

      +
      +

      Description

      +

      podIP holds options related to Pod IP address.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      source

      string

      sourceType specifies source of the Pod IP.

      +
      +
      +
      +

      .spec.exposeOptions.cql

      +
      +

      Description

      +

      cql specifies expose options for CQL SSL backend. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      ingress

      object

      ingress is an Ingress configuration options. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      +
      +
      +
      +

      .spec.exposeOptions.cql.ingress

      +
      +

      Description

      +

      ingress is an Ingress configuration options. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      annotations

      object

      annotations specifies custom annotations merged into every Ingress object. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      disabled

      boolean

      disabled controls if Ingress object creation is disabled. Unless disabled, there is an Ingress objects created for every Scylla node. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      ingressClassName

      string

      ingressClassName specifies Ingress class name. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      +
      +
      +
      +

      .spec.exposeOptions.cql.ingress.annotations

      +
      +

      Description

      +

      annotations specifies custom annotations merged into every Ingress object. EXPERIMENTAL. Do not rely on any particular behaviour controlled by this field.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.exposeOptions.nodeService

      +
      +

      Description

      +

      nodeService controls properties of Service dedicated for each ScyllaCluster node.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      allocateLoadBalancerNodePorts

      boolean

      allocateLoadBalancerNodePorts controls value of service.spec.allocateLoadBalancerNodePorts of each node Service. Check Kubernetes corev1.Service documentation about semantic of this field.

      annotations

      object

      annotations is a custom key value map merged with every node Service annotations.

      externalTrafficPolicy

      string

      externalTrafficPolicy controls value of service.spec.externalTrafficPolicy of each node Service. Check Kubernetes corev1.Service documentation about semantic of this field.

      internalTrafficPolicy

      string

      internalTrafficPolicy controls value of service.spec.internalTrafficPolicy of each node Service. Check Kubernetes corev1.Service documentation about semantic of this field.

      loadBalancerClass

      string

      loadBalancerClass controls value of service.spec.loadBalancerClass of each node Service. Check Kubernetes corev1.Service documentation about semantic of this field.

      type

      string

      type is the Kubernetes Service type.

      +
      +
      +
      +

      .spec.exposeOptions.nodeService.annotations

      +
      +

      Description

      +

      annotations is a custom key value map merged with every node Service annotations.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.genericUpgrade

      +
      +

      Description

      +

      genericUpgrade allows to configure behavior of generic upgrade logic.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      failureStrategy

      string

      failureStrategy specifies which logic is executed when upgrade failure happens. Currently only Retry is supported.

      pollInterval

      string

      pollInterval specifies how often upgrade logic polls on state updates. Increasing this value should lower number of requests sent to apiserver, but it may affect overall time spent during upgrade. DEPRECATED.

      +
      +
      +
      +

      .spec.imagePullSecrets[]

      +
      +

      Description

      +

      LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?

      +
      +
      +
      +

      .spec.network

      +
      +

      Description

      +

      network holds the networking config.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      dnsPolicy

      string

      dnsPolicy defines how a pod’s DNS will be configured.

      hostNetworking

      boolean

      hostNetworking determines if scylla uses the host’s network namespace. Setting this option avoids going through Kubernetes SDN and exposes scylla on node’s IP.

      +
      +
      +
      +

      .spec.repairs[]

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      dc

      array (string)

      dc is a list of datacenter glob patterns, e.g. ‘dc1’, ‘!otherdc*’ used to specify the DCs to include or exclude from backup.

      failFast

      boolean

      failFast indicates if a repair should be stopped on first error.

      host

      string

      host specifies a host to repair. If empty, all hosts are repaired.

      intensity

      string

      intensity indicates how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. For Scylla clusters that do not support row-level repair, intensity can be a decimal between (0,1). In that case it specifies percent of shards that can be repaired in parallel on a repair master node. For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1.

      interval

      string

      interval represents a task schedule interval e.g. 3d2h10m, valid units are d, h, m, s.

      keyspace

      array (string)

      keyspace is a list of keyspace/tables glob patterns, e.g. ‘keyspace,!keyspace.table_prefix_*’ used to include or exclude keyspaces from repair.

      name

      string

      name is a unique name of a task.

      numRetries

      integer

      numRetries indicates how many times a scheduled task will be retried before failing.

      parallel

      integer

      parallel is the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2.

      smallTableThreshold

      string

      smallTableThreshold enable small table optimization for tables of size lower than given threshold. Supported units [B, MiB, GiB, TiB].

      startDate

      string

      startDate specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, valid units are d, h, m, s.

      +
      +
      +
      +

      .status

      +
      +

      Description

      +

      status is the current status of this scylla cluster.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      backups

      array (object)

      backups reflects status of backup tasks.

      conditions

      array (object)

      conditions hold conditions describing ScyllaCluster state. To determine whether a cluster rollout is finished, look for Available=True,Progressing=False,Degraded=False.

      managerId

      string

      managerId contains ID under which cluster was registered in Scylla Manager.

      observedGeneration

      integer

      observedGeneration is the most recent generation observed for this ScyllaCluster. It corresponds to the ScyllaCluster’s generation, which is updated on mutation by the API Server.

      racks

      object

      racks reflect status of cluster racks.

      repairs

      array (object)

      repairs reflects status of repair tasks.

      upgrade

      object

      upgrade reflects state of ongoing upgrade procedure.

      +
      +
      +
      +

      .status.backups[]

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      dc

      array (string)

      dc is a list of datacenter glob patterns, e.g. ‘dc1,!otherdc*’ used to specify the DCs to include or exclude from backup.

      error

      string

      error holds the backup task error, if any.

      id

      string

      id is the identification number of the backup task.

      interval

      string

      interval represents a task schedule interval e.g. 3d2h10m, valid units are d, h, m, s.

      keyspace

      array (string)

      keyspace is a list of keyspace/tables glob patterns, e.g. ‘keyspace,!keyspace.table_prefix_*’ used to include or exclude keyspaces from repair.

      location

      array (string)

      location is a list of backup locations in the format [<dc>:]<provider>:<name> ex. s3:my-bucket. The <dc>: part is optional and is only needed when different datacenters are being used to upload data to different locations. <name> must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. The only supported storage <provider> at the moment are s3 and gcs.

      name

      string

      name is a unique name of a task.

      numRetries

      integer

      numRetries indicates how many times a scheduled task will be retried before failing.

      rateLimit

      array (string)

      rateLimit is a list of megabytes (MiB) per second rate limits expressed in the format [<dc>:]<limit>. The <dc>: part is optional and only needed when different datacenters need different upload limits. Set to 0 for no limit (default 100).

      retention

      integer

      retention is the number of backups which are to be stored.

      snapshotParallel

      array (string)

      snapshotParallel is a list of snapshot parallelism limits in the format [<dc>:]<limit>. The <dc>: part is optional and allows for specifying different limits in selected datacenters. If The <dc>: part is not set, the limit is global (e.g. ‘dc1:2,5’) the runs are parallel in n nodes (2 in dc1) and n nodes in all the other datacenters.

      startDate

      string

      startDate specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, valid units are d, h, m, s.

      uploadParallel

      array (string)

      uploadParallel is a list of upload parallelism limits in the format [<dc>:]<limit>. The <dc>: part is optional and allows for specifying different limits in selected datacenters. If The <dc>: part is not set the limit is global (e.g. ‘dc1:2,5’) the runs are parallel in n nodes (2 in dc1) and n nodes in all the other datacenters.

      +
      +
      +
      +

      .status.conditions[]

      +
      +

      Description

      +
      +
      Condition contains details for one aspect of the current state of this API Resource. — This struct is intended for direct use as an array at the field path .status.conditions. For example,

      type FooStatus struct{ // Represents the observations of a foo’s current state. // Known .status.conditions.type are: “Available”, “Progressing”, and “Degraded” // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition json:”conditions,omitempty” patchStrategy:”merge” patchMergeKey:”type” protobuf:”bytes,1,rep,name=conditions” +// other fields }

      +
      +
      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      lastTransitionTime

      string

      lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.

      message

      string

      message is a human readable message indicating details about the transition. This may be an empty string.

      observedGeneration

      integer

      observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

      reason

      string

      reason contains a programmatic identifier indicating the reason for the condition’s last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.

      status

      string

      status of the condition, one of True, False, Unknown.

      type

      string

      type of condition in CamelCase or in foo.example.com/CamelCase. — Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)

      +
      +
      +
      +

      .status.racks

      +
      +

      Description

      +

      racks reflect status of cluster racks.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .status.repairs[]

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      dc

      array (string)

      dc is a list of datacenter glob patterns, e.g. ‘dc1’, ‘!otherdc*’ used to specify the DCs to include or exclude from backup.

      error

      string

      error holds the repair task error, if any.

      failFast

      boolean

      failFast indicates if a repair should be stopped on first error.

      host

      string

      host specifies a host to repair. If empty, all hosts are repaired.

      id

      string

      id is the identification number of the repair task.

      intensity

      string

      intensity indicates how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. For Scylla clusters that do not support row-level repair, intensity can be a decimal between (0,1). In that case it specifies percent of shards that can be repaired in parallel on a repair master node. For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1.

      interval

      string

      interval represents a task schedule interval e.g. 3d2h10m, valid units are d, h, m, s.

      keyspace

      array (string)

      keyspace is a list of keyspace/tables glob patterns, e.g. ‘keyspace,!keyspace.table_prefix_*’ used to include or exclude keyspaces from repair.

      name

      string

      name is a unique name of a task.

      numRetries

      integer

      numRetries indicates how many times a scheduled task will be retried before failing.

      parallel

      integer

      parallel is the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2.

      smallTableThreshold

      string

      smallTableThreshold enable small table optimization for tables of size lower than given threshold. Supported units [B, MiB, GiB, TiB].

      startDate

      string

      startDate specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, valid units are d, h, m, s.

      +
      +
      +
      +

      .status.upgrade

      +
      +

      Description

      +

      upgrade reflects state of ongoing upgrade procedure.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      currentNode

      string

      currentNode node under upgrade. DEPRECATED.

      currentRack

      string

      currentRack rack under upgrade. DEPRECATED.

      dataSnapshotTag

      string

      dataSnapshotTag is the snapshot tag of data keyspaces.

      fromVersion

      string

      fromVersion reflects from which version ScyllaCluster is being upgraded.

      state

      string

      state reflects current upgrade state.

      systemSnapshotTag

      string

      systemSnapshotTag is the snapshot tag of system keyspaces.

      toVersion

      string

      toVersion reflects to which version ScyllaCluster is being upgraded.

      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/api-reference/groups/scylla.scylladb.com/scylladbmonitorings.html b/master/api-reference/groups/scylla.scylladb.com/scylladbmonitorings.html new file mode 100644 index 00000000000..a88f4c8f35f --- /dev/null +++ b/master/api-reference/groups/scylla.scylladb.com/scylladbmonitorings.html @@ -0,0 +1,5288 @@ + + + + + + + + + + + + + ScyllaDBMonitoring (scylla.scylladb.com/v1alpha1) | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      ScyllaDBMonitoring (scylla.scylladb.com/v1alpha1)

      +
      +
      APIVersion: scylla.scylladb.com/v1alpha1
      +
      Kind: ScyllaDBMonitoring
      +
      PluralName: scylladbmonitorings
      +
      SingularName: scylladbmonitoring
      +
      Scope: Namespaced
      +
      ListKind: ScyllaDBMonitoringList
      +
      Served: true
      +
      Storage: true
      +
      +
      +

      Description

      +

      ScyllaDBMonitoring defines a monitoring instance for ScyllaDB clusters.

      +
      +
      +

      Specification

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

      Property

      Type

      Description

      apiVersion

      string

      APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

      kind

      string

      Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

      metadata

      object

      spec

      object

      spec defines the desired state of this ScyllaDBMonitoring.

      status

      object

      status is the current status of this ScyllaDBMonitoring.

      +
      +

      .metadata

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec

      +
      +

      Description

      +

      spec defines the desired state of this ScyllaDBMonitoring.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      components

      object

      components hold additional config for the monitoring components in use.

      endpointsSelector

      object

      endpointsSelector select which Endpoints should be scraped. For local ScyllaDB clusters or datacenters, this is the same selector as if you were trying to select member Services. For remote ScyllaDB clusters, this can select any endpoints that are created manually or for a Service without selectors.

      type

      string

      type determines the platform type of the monitoring setup.

      +
      +
      +
      +

      .spec.components

      +
      +

      Description

      +

      components hold additional config for the monitoring components in use.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      grafana

      object

      grafana holds configuration for the grafana instance, if any.

      prometheus

      object

      prometheus holds configuration for the prometheus instance, if any.

      +
      +
      +
      +

      .spec.components.grafana

      +
      +

      Description

      +

      grafana holds configuration for the grafana instance, if any.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      authentication

      object

      authentication hold the authentication options for accessing Grafana.

      exposeOptions

      object

      exposeOptions specifies options for exposing Grafana UI.

      placement

      object

      placement describes restrictions for the nodes Grafana is scheduled on.

      resources

      object

      resources the Grafana container will use.

      servingCertSecretName

      string

      servingCertSecretName is the name of the secret holding a serving cert-key pair. If not specified, the operator will create a self-signed CA that creates the default serving cert-key pair.

      +
      +
      +
      +

      .spec.components.grafana.authentication

      +
      +

      Description

      +

      authentication hold the authentication options for accessing Grafana.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      insecureEnableAnonymousAccess

      boolean

      insecureEnableAnonymousAccess allows access to Grafana without authentication.

      +
      +
      +
      +

      .spec.components.grafana.exposeOptions

      +
      +

      Description

      +

      exposeOptions specifies options for exposing Grafana UI.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      webInterface

      object

      webInterface specifies expose options for the user web interface.

      +
      +
      +
      +

      .spec.components.grafana.exposeOptions.webInterface

      +
      +

      Description

      +

      webInterface specifies expose options for the user web interface.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      ingress

      object

      ingress is an Ingress configuration options.

      +
      +
      +
      +

      .spec.components.grafana.exposeOptions.webInterface.ingress

      +
      +

      Description

      +

      ingress is an Ingress configuration options.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      annotations

      object

      annotations specifies custom annotations merged into every Ingress object.

      disabled

      boolean

      disabled controls if Ingress object creation is disabled.

      dnsDomains

      array (string)

      dnsDomains is a list of DNS domains this ingress is reachable by.

      ingressClassName

      string

      ingressClassName specifies Ingress class name.

      +
      +
      +
      +

      .spec.components.grafana.exposeOptions.webInterface.ingress.annotations

      +
      +

      Description

      +

      annotations specifies custom annotations merged into every Ingress object.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.placement

      +
      +

      Description

      +

      placement describes restrictions for the nodes Grafana is scheduled on.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      nodeAffinity

      object

      nodeAffinity describes node affinity scheduling rules for the pod.

      podAffinity

      object

      podAffinity describes pod affinity scheduling rules.

      podAntiAffinity

      object

      podAntiAffinity describes pod anti-affinity scheduling rules.

      tolerations

      array (object)

      tolerations allow the pod to tolerate any taint that matches the triple <key,value,effect> using the matching operator.

      +
      +
      +
      +

      .spec.components.grafana.placement.nodeAffinity

      +
      +

      Description

      +

      nodeAffinity describes node affinity scheduling rules for the pod.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      object

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

      +
      +
      +
      +

      .spec.components.grafana.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it’s a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preference

      object

      A node selector term, associated with the corresponding weight.

      weight

      integer

      Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.components.grafana.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference

      +
      +

      Description

      +

      A node selector term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      A list of node selector requirements by node’s labels.

      matchFields

      array (object)

      A list of node selector requirements by node’s fields.

      +
      +
      +
      +

      .spec.components.grafana.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchExpressions[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchFields[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution

      +
      +

      Description

      +

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      nodeSelectorTerms

      array (object)

      Required. A list of node selector terms. The terms are ORed.

      +
      +
      +
      +

      .spec.components.grafana.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[]

      +
      +

      Description

      +

      A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      A list of node selector requirements by node’s labels.

      matchFields

      array (object)

      A list of node selector requirements by node’s fields.

      +
      +
      +
      +

      .spec.components.grafana.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchExpressions[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchFields[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity

      +
      +

      Description

      +

      podAffinity describes pod affinity scheduling rules.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      array (object)

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podAffinityTerm

      object

      Required. A pod affinity term, associated with the corresponding weight.

      weight

      integer

      weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm

      +
      +

      Description

      +

      Required. A pod affinity term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity

      +
      +

      Description

      +

      podAntiAffinity describes pod anti-affinity scheduling rules.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      array (object)

      If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podAffinityTerm

      object

      Required. A pod affinity term, associated with the corresponding weight.

      weight

      integer

      weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm

      +
      +

      Description

      +

      Required. A pod affinity term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.placement.tolerations[]

      +
      +

      Description

      +

      The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      effect

      string

      Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.

      key

      string

      Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys.

      operator

      string

      Operator represents a key’s relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.

      tolerationSeconds

      integer

      TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.

      value

      string

      Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.

      +
      +
      +
      +

      .spec.components.grafana.resources

      +
      +

      Description

      +

      resources the Grafana container will use.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      claims

      array (object)

      +
      Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.

      This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. +This field is immutable. It can only be set for containers.

      +
      +
      +

      limits

      object

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      requests

      object

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +
      +

      .spec.components.grafana.resources.claims[]

      +
      +

      Description

      +

      ResourceClaim references one entry in PodSpec.ResourceClaims.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.

      +
      +
      +
      +

      .spec.components.grafana.resources.limits

      +
      +

      Description

      +

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.grafana.resources.requests

      +
      +

      Description

      +

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus

      +
      +

      Description

      +

      prometheus holds configuration for the prometheus instance, if any.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      exposeOptions

      object

      exposeOptions specifies options for exposing Prometheus UI.

      placement

      object

      placement describes restrictions for the nodes Prometheus is scheduled on.

      resources

      object

      resources the Prometheus container will use.

      storage

      object

      storage describes the underlying storage that Prometheus will consume.

      +
      +
      +
      +

      .spec.components.prometheus.exposeOptions

      +
      +

      Description

      +

      exposeOptions specifies options for exposing Prometheus UI.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      webInterface

      object

      webInterface specifies expose options for the user web interface.

      +
      +
      +
      +

      .spec.components.prometheus.exposeOptions.webInterface

      +
      +

      Description

      +

      webInterface specifies expose options for the user web interface.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      ingress

      object

      ingress is an Ingress configuration options.

      +
      +
      +
      +

      .spec.components.prometheus.exposeOptions.webInterface.ingress

      +
      +

      Description

      +

      ingress is an Ingress configuration options.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      annotations

      object

      annotations specifies custom annotations merged into every Ingress object.

      disabled

      boolean

      disabled controls if Ingress object creation is disabled.

      dnsDomains

      array (string)

      dnsDomains is a list of DNS domains this ingress is reachable by.

      ingressClassName

      string

      ingressClassName specifies Ingress class name.

      +
      +
      +
      +

      .spec.components.prometheus.exposeOptions.webInterface.ingress.annotations

      +
      +

      Description

      +

      annotations specifies custom annotations merged into every Ingress object.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.placement

      +
      +

      Description

      +

      placement describes restrictions for the nodes Prometheus is scheduled on.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      nodeAffinity

      object

      nodeAffinity describes node affinity scheduling rules for the pod.

      podAffinity

      object

      podAffinity describes pod affinity scheduling rules.

      podAntiAffinity

      object

      podAntiAffinity describes pod anti-affinity scheduling rules.

      tolerations

      array (object)

      tolerations allow the pod to tolerate any taint that matches the triple <key,value,effect> using the matching operator.

      +
      +
      +
      +

      .spec.components.prometheus.placement.nodeAffinity

      +
      +

      Description

      +

      nodeAffinity describes node affinity scheduling rules for the pod.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      object

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

      +
      +
      +
      +

      .spec.components.prometheus.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it’s a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preference

      object

      A node selector term, associated with the corresponding weight.

      weight

      integer

      Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.components.prometheus.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference

      +
      +

      Description

      +

      A node selector term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      A list of node selector requirements by node’s labels.

      matchFields

      array (object)

      A list of node selector requirements by node’s fields.

      +
      +
      +
      +

      .spec.components.prometheus.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchExpressions[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchFields[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution

      +
      +

      Description

      +

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      nodeSelectorTerms

      array (object)

      Required. A list of node selector terms. The terms are ORed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[]

      +
      +

      Description

      +

      A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      A list of node selector requirements by node’s labels.

      matchFields

      array (object)

      A list of node selector requirements by node’s fields.

      +
      +
      +
      +

      .spec.components.prometheus.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchExpressions[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchFields[]

      +
      +

      Description

      +

      A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      The label key that the selector applies to.

      operator

      string

      Represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.

      values

      array (string)

      An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity

      +
      +

      Description

      +

      podAffinity describes pod affinity scheduling rules.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      array (object)

      If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podAffinityTerm

      object

      Required. A pod affinity term, associated with the corresponding weight.

      weight

      integer

      weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm

      +
      +

      Description

      +

      Required. A pod affinity term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity

      +
      +

      Description

      +

      podAntiAffinity describes pod anti-affinity scheduling rules.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      preferredDuringSchedulingIgnoredDuringExecution

      array (object)

      The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.

      requiredDuringSchedulingIgnoredDuringExecution

      array (object)

      If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      podAffinityTerm

      object

      Required. A pod affinity term, associated with the corresponding weight.

      weight

      integer

      weight associated with matching the corresponding podAffinityTerm, in the range 1-100.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm

      +
      +

      Description

      +

      Required. A pod affinity term, associated with the corresponding weight.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[]

      +
      +

      Description

      +

      Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key <topologyKey> matches that of any node on which a pod of the set of pods is running

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      labelSelector

      object

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      matchLabelKeys

      array (string)

      MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key in (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. Also, MatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      mismatchLabelKeys

      array (string)

      MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with LabelSelector as key notin (value) to select the group of existing pods which pods will be taken into consideration for the incoming pod’s pod (anti) affinity. Keys that don’t exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. Also, MismatchLabelKeys cannot be set when LabelSelector isn’t set. This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate.

      namespaceSelector

      object

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      namespaces

      array (string)

      namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means “this pod’s namespace”.

      topologyKey

      string

      This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector

      +
      +

      Description

      +

      A label query over a set of resources, in this case pods. If it’s null, this PodAffinityTerm matches with no Pods.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector

      +
      +

      Description

      +

      A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means “this pod’s namespace”. An empty selector ({}) matches all namespaces.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.placement.tolerations[]

      +
      +

      Description

      +

      The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      effect

      string

      Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.

      key

      string

      Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys.

      operator

      string

      Operator represents a key’s relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.

      tolerationSeconds

      integer

      TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.

      value

      string

      Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.

      +
      +
      +
      +

      .spec.components.prometheus.resources

      +
      +

      Description

      +

      resources the Prometheus container will use.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      claims

      array (object)

      +
      Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.

      This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. +This field is immutable. It can only be set for containers.

      +
      +
      +

      limits

      object

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      requests

      object

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +
      +

      .spec.components.prometheus.resources.claims[]

      +
      +

      Description

      +

      ResourceClaim references one entry in PodSpec.ResourceClaims.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      name

      string

      Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.

      +
      +
      +
      +

      .spec.components.prometheus.resources.limits

      +
      +

      Description

      +

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.resources.requests

      +
      +

      Description

      +

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.storage

      +
      +

      Description

      +

      storage describes the underlying storage that Prometheus will consume.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      annotations

      object

      Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations

      labels

      object

      Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels

      volumeClaimTemplate

      object

      volumeClaimTemplates is a PVC template defining storage to be used by Prometheus.

      +
      +
      +
      +

      .spec.components.prometheus.storage.annotations

      +
      +

      Description

      +

      Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.storage.labels

      +
      +

      Description

      +

      Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate

      +
      +

      Description

      +

      volumeClaimTemplates is a PVC template defining storage to be used by Prometheus.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      metadata

      object

      May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation.

      spec

      object

      The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here.

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.metadata

      +
      +

      Description

      +

      May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.spec

      +
      +

      Description

      +

      The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      accessModes

      array (string)

      accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1

      dataSource

      object

      dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.

      dataSourceRef

      object

      dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn’t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn’t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.

      resources

      object

      resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources

      selector

      object

      selector is a label query over volumes to consider for binding.

      storageClassName

      string

      storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1

      volumeAttributesClassName

      string

      volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. If specified, the CSI driver will create or update the volume with the attributes defined in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass will be applied to the claim but it’s not allowed to reset this field to empty string once it is set. If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass will be set by the persistentvolume controller if it exists. If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled.

      volumeMode

      string

      volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.

      volumeName

      string

      volumeName is the binding reference to the PersistentVolume backing this claim.

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.spec.dataSource

      +
      +

      Description

      +

      dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      apiGroup

      string

      APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.

      kind

      string

      Kind is the type of resource being referenced

      name

      string

      Name is the name of resource being referenced

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.spec.dataSourceRef

      +
      +

      Description

      +

      dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn’t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn’t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      apiGroup

      string

      APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.

      kind

      string

      Kind is the type of resource being referenced

      name

      string

      Name is the name of resource being referenced

      namespace

      string

      Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace’s owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.spec.resources

      +
      +

      Description

      +

      resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      limits

      object

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      requests

      object

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.spec.resources.limits

      +
      +

      Description

      +

      Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.spec.resources.requests

      +
      +

      Description

      +

      Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.spec.selector

      +
      +

      Description

      +

      selector is a label query over volumes to consider for binding.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.spec.selector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.components.prometheus.storage.volumeClaimTemplate.spec.selector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec.endpointsSelector

      +
      +

      Description

      +

      endpointsSelector select which Endpoints should be scraped. For local ScyllaDB clusters or datacenters, this is the same selector as if you were trying to select member Services. For remote ScyllaDB clusters, this can select any endpoints that are created manually or for a Service without selectors.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      matchExpressions

      array (object)

      matchExpressions is a list of label selector requirements. The requirements are ANDed.

      matchLabels

      object

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +
      +

      .spec.endpointsSelector.matchExpressions[]

      +
      +

      Description

      +

      A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      key

      string

      key is the label key that the selector applies to.

      operator

      string

      operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.

      values

      array (string)

      values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.

      +
      +
      +
      +

      .spec.endpointsSelector.matchLabels

      +
      +

      Description

      +

      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .status

      +
      +

      Description

      +

      status is the current status of this ScyllaDBMonitoring.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      conditions

      array (object)

      conditions hold conditions describing ScyllaDBMonitoring state. To determine whether a cluster rollout is finished, look for Available=True,Progressing=False,Degraded=False.

      observedGeneration

      integer

      observedGeneration is the most recent generation observed for this ScyllaDBMonitoring. It corresponds to the ScyllaDBMonitoring’s generation, which is updated on mutation by the API Server.

      +
      +
      +
      +

      .status.conditions[]

      +
      +

      Description

      +
      +
      Condition contains details for one aspect of the current state of this API Resource. — This struct is intended for direct use as an array at the field path .status.conditions. For example,

      type FooStatus struct{ // Represents the observations of a foo’s current state. // Known .status.conditions.type are: “Available”, “Progressing”, and “Degraded” // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition json:”conditions,omitempty” patchStrategy:”merge” patchMergeKey:”type” protobuf:”bytes,1,rep,name=conditions” +// other fields }

      +
      +
      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      lastTransitionTime

      string

      lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.

      message

      string

      message is a human readable message indicating details about the transition. This may be an empty string.

      observedGeneration

      integer

      observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

      reason

      string

      reason contains a programmatic identifier indicating the reason for the condition’s last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.

      status

      string

      status of the condition, one of True, False, Unknown.

      type

      string

      type of condition in CamelCase or in foo.example.com/CamelCase. — Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)

      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/api-reference/groups/scylla.scylladb.com/scyllaoperatorconfigs.html b/master/api-reference/groups/scylla.scylladb.com/scyllaoperatorconfigs.html new file mode 100644 index 00000000000..bd4d3e7d60c --- /dev/null +++ b/master/api-reference/groups/scylla.scylladb.com/scyllaoperatorconfigs.html @@ -0,0 +1,734 @@ + + + + + + + + + + + + + ScyllaOperatorConfig (scylla.scylladb.com/v1alpha1) | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      ScyllaOperatorConfig (scylla.scylladb.com/v1alpha1)

      +
      +
      APIVersion: scylla.scylladb.com/v1alpha1
      +
      Kind: ScyllaOperatorConfig
      +
      PluralName: scyllaoperatorconfigs
      +
      SingularName: scyllaoperatorconfig
      +
      Scope: Cluster
      +
      ListKind: ScyllaOperatorConfigList
      +
      Served: true
      +
      Storage: true
      +
      +
      +

      Description

      +

      ScyllaOperatorConfig describes the Scylla Operator configuration.

      +
      +
      +

      Specification

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

      Property

      Type

      Description

      apiVersion

      string

      APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

      kind

      string

      Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

      metadata

      object

      spec

      object

      spec defines the desired state of the operator.

      status

      object

      status defines the observed state of the operator.

      +
      +

      .metadata

      +
      +

      Description

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +

      .spec

      +
      +

      Description

      +

      spec defines the desired state of the operator.

      +
      +
      +

      Type

      +

      object

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

      Property

      Type

      Description

      scyllaUtilsImage

      string

      scyllaUtilsImage is a Scylla image used for running scylla utilities.

      +
      +
      +
      +

      .status

      +
      +

      Description

      +

      status defines the observed state of the operator.

      +
      +
      +

      Type

      +

      object

      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/api-reference/index.html b/master/api-reference/index.html new file mode 100644 index 00000000000..1462d4f28f1 --- /dev/null +++ b/master/api-reference/index.html @@ -0,0 +1,615 @@ + + + + + + + + + + + + + API Reference | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      API Reference

      +

      All APIs provided by Scylla Operator are defined using CRDs and adhere to Kubernetes API standards. You can find out how Kubernetes style REST APIs work on https://kubernetes.io/docs/reference/using-api/ and https://kubernetes.io/docs/reference/access-authn-authz/.

      +
      +

      API Groups and Kinds

      + +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/contributing.html b/master/contributing.html new file mode 100644 index 00000000000..f8aebefe8f9 --- /dev/null +++ b/master/contributing.html @@ -0,0 +1,756 @@ + + + + + + + + + + + + + Contributing to Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Contributing to Scylla Operator

      +
      +

      Prerequisites

      +

      To develop on scylla-operator, your environment must have the following:

      +
        +
      1. Go 1.13

        +
          +
        • Make sure GOPATH is set to GOPATH=$HOME/go.

        • +
        +
      2. +
      3. Kustomize v3.1.0

      4. +
      5. kubebuilder v2.3.1

      6. +
      7. Docker

      8. +
      9. Git client installed

      10. +
      11. Github account

      12. +
      +

      To install all dependencies (Go, kustomize, kubebuilder, dep), simply run:

      +
      ./install-dependencies.sh
      +
      +
      +
      +
      +

      Initial Setup

      +
      +

      Create a Fork

      +

      From your browser navigate to http://github.com/scylladb/scylla-operator and click the “Fork” button.

      +
      +
      +

      Clone Your Fork

      +

      Open a console window and do the following:

      +
      # Create the scylla operator repo path
      +mkdir -p $GOPATH/src/github.com/scylladb
      +
      +# Navigate to the local repo path and clone your fork
      +cd $GOPATH/src/github.com/scylladb
      +
      +# Clone your fork, where <user> is your GitHub account name
      +git clone https://github.com/<user>/scylla-operator.git
      +
      +
      +
      +
      +

      Add Upstream Remote

      +

      First you will need to add the upstream remote to your local git:

      +
      # Add 'upstream' to the list of remotes
      +git remote add upstream https://github.com/scylladb/scylla-operator.git
      +
      +# Verify the remote was added
      +git remote -v
      +
      +
      +

      Now you should have at least origin and upstream remotes. You can also add other remotes to collaborate with other contributors.

      +
      +
      +
      +

      Development

      +

      To add a feature or to make a bug fix, you will need to create a branch in your fork and then submit a pull request (PR) from the branch.

      +
      +

      Building the project

      +

      You can build the project using the Makefile commands:

      +
        +
      • Open the Makefile and change the IMG environment variable to a repository you have access to.

      • +
      • Run make docker-push and wait for the image to be built and uploaded in your repo.

      • +
      +
      +
      +

      Create a Branch

      +

      From a console, create a new branch based on your fork and start working on it:

      +
      # Ensure all your remotes are up to date with the latest
      +git fetch --all
      +
      +# Create a new branch that is based off upstream master.  Give it a simple, but descriptive name.
      +# Generally it will be two to three words separated by dashes and without numbers.
      +git checkout -b feature-name upstream/master
      +
      +
      +

      Now you are ready to make the changes and commit to your branch.

      +
      +
      +

      Updating Your Fork

      +

      During the development lifecycle, you will need to keep up-to-date with the latest upstream master. As others on the team push changes, you will need to rebase your commits on top of the latest. This avoids unnecessary merge commits and keeps the commit history clean.

      +

      Whenever you need to update your local repository, you never want to merge. You always will rebase. Otherwise you will end up with merge commits in the git history. If you have any modified files, you will first have to stash them (git stash save -u "<some description>").

      +
      git fetch --all
      +git rebase upstream/master
      +
      +
      +

      Rebasing is a very powerful feature of Git. You need to understand how it works or else you will risk losing your work. Read about it in the Git documentation, it will be well worth it. In a nutshell, rebasing does the following:

      +
        +
      • “Unwinds” your local commits. Your local commits are removed temporarily from the history.

      • +
      • The latest changes from upstream are added to the history

      • +
      • Your local commits are re-applied one by one

      • +
      • If there are merge conflicts, you will be prompted to fix them before continuing. Read the output closely. It will tell you how to complete the rebase.

      • +
      • When done rebasing, you will see all of your commits in the history.

      • +
      +
      +
      +
      +

      Submitting a Pull Request

      +

      Once you have implemented the feature or bug fix in your branch, you will open a PR to the upstream repo. Before opening the PR ensure you have added unit tests, are passing the integration tests, cleaned your commit history, and have rebased on the latest upstream.

      +

      In order to open a pull request (PR) it is required to be up to date with the latest changes upstream. If other commits are pushed upstream before your PR is merged, you will also need to rebase again before it will be merged.

      +
      +

      Commit History

      +

      To prepare your branch to open a PR, you will need to have the minimal number of logical commits so we can maintain +a clean commit history. Most commonly a PR will include a single commit where all changes are squashed, although +sometimes there will be multiple logical commits.

      +
      # Inspect your commit history to determine if you need to squash commits
      +git log
      +
      +# Rebase the commits and edit, squash, or even reorder them as you determine will keep the history clean.
      +# In this example, the last 5 commits will be opened in the git rebase tool.
      +git rebase -i HEAD~5
      +
      +
      +

      Once your commit history is clean, ensure you have based on the latest upstream before you open the PR.

      +
      +
      +

      Commit messages

      +

      Please make the first line of your commit message a summary of the change that a user (not a developer) of Operator would like to read, +and prefix it with the most relevant directory of the change followed by a colon. +The changelog gets made by looking at just these first lines so make it good!

      +

      If you have more to say about the commit, then enter a blank line and carry on the description. +Remember to say why the change was needed - the commit itself shows what was changed.

      +

      Writing more is better than less. Comparing the behaviour before the change to that after the change is very useful. +Imagine you are writing to yourself in 12 months time when you’ve forgotten everything about what you just did, and you need to get up to speed quickly.

      +

      If the change fixes an issue then write Fixes #1234 in the commit message. +This can be on the subject line if it will fit. If you don’t want to close the associated issue just put #1234 and the change will get linked into the issue.

      +

      Here is an example of a short commit message:

      +
      sidecar: log on reconcile loop - fixes #1234
      +
      +
      +

      And here is an example of a longer one:

      +
      
      +api: now supports host networking (#1234)
      +
      +The operator CRD now has a "network" property that can be used to
      +select host networking as well as setting the apropriate DNS policy.
      +
      +Fixes #1234
      +
      +
      +
      +
      +

      Submitting

      +

      Go to the Scylla Operator github to open the PR. If you have pushed recently, you should see an obvious link to open the PR. If you have not pushed recently, go to the Pull Request tab and select your fork and branch for the PR.

      +

      After the PR is open, you can make changes simply by pushing new commits. Your PR will track the changes in your fork and update automatically.

      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/eks.html b/master/eks.html new file mode 100644 index 00000000000..503643dd883 --- /dev/null +++ b/master/eks.html @@ -0,0 +1,751 @@ + + + + + + + + + + + + + Deploying Scylla on EKS | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Deploying Scylla on EKS

      +

      This guide is focused on deploying Scylla on EKS with improved performance. +Performance tricks used by the script won’t work with different machine tiers. +It sets up the kubelets on EKS nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

      +

      Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

      +
      +

      TL;DR;

      +

      If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

      +
      # Edit according to your preference
      +EKS_REGION=us-east-1
      +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
      +
      +# From inside the examples/eks folder
      +cd examples/eks
      +./eks.sh -z "$EKS_ZONES" -r "$EKS_REGION"
      +
      +
      +

      After you deploy, see how you can benchmark your cluster with cassandra-stress.

      +
      +
      +

      Walkthrough

      +
      +

      EKS Setup

      +
      +

      Configure environment variables

      +

      First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

      +
      EKS_REGION=us-east-1
      +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
      +CLUSTER_NAME=scylla-demo
      +
      +
      +
      +
      +

      Creating an EKS cluster

      +

      For this guide, we’ll create an EKS cluster with the following:

      +
        +
      • A NodeGroup of 3 i3-2xlarge Nodes, where the Scylla Pods will be deployed. These nodes will only accept pods having scylla-clusters toleration.

      • +
      +
        - name: scylla-pool
      +    instanceType: i3.2xlarge
      +    desiredCapacity: 3
      +    labels:
      +      scylla.scylladb.com/node-type: scylla
      +    taints:
      +      role: "scylla-clusters:NoSchedule"
      +    ssh:
      +      allow: true
      +    kubeletExtraConfig:
      +      cpuManagerPolicy: static
      +
      +
      +
        +
      • A NodeGroup of 4 c4.2xlarge Nodes to deploy cassandra-stress later on. These nodes will only accept pods having cassandra-stress toleration.

      • +
      +
        - name: cassandra-stress-pool
      +    instanceType: c4.2xlarge
      +    desiredCapacity: 4
      +    labels:
      +      pool: "cassandra-stress-pool"
      +    taints:
      +      role: "cassandra-stress:NoSchedule"
      +    ssh:
      +      allow: true
      +
      +
      +
        +
      • A NodeGroup of 1 i3.large Node, where the monitoring stack and operator will be deployed.

      • +
      +
        - name: monitoring-pool
      +    instanceType: i3.large
      +    desiredCapacity: 1
      +    labels:
      +      pool: "monitoring-pool"
      +    ssh:
      +      allow: true
      +
      +
      +
      +
      +
      +

      Prerequisites

      +
      +

      Installing script third party dependencies

      +

      Script requires several dependencies:

      +
        +
      • eksctl - See: https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html

      • +
      • kubectl - See: https://kubernetes.io/docs/tasks/tools/install-kubectl/

      • +
      +
      +
      +
      +

      Deploying ScyllaDB Operator

      +

      Refer to Deploying Scylla on a Kubernetes Cluster in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites.

      +
      +

      Setting up nodes for ScyllaDB

      +

      ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you’ll first need to form a RAID array from those disks. +NodeConfig performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in Performance tuning section of ScyllaDB Operator’s documentation.

      +

      Deploy NodeConfig to let it take care of the above operations:

      +
      kubectl apply --server-side -f examples/eks/nodeconfig-alpha.yaml
      +
      +
      +
      +
      +

      Deploying Local Volume Provisioner

      +

      Afterwards, deploy ScyllaDB’s Local Volume Provisioner, capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays.

      +
      kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/
      +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml
      +
      +
      +
      +
      +
      +

      Deploying ScyllaDB

      +

      Now you can follow the steps described in Deploying Scylla on a Kubernetes Cluster to launch your ScyllaDB cluster in a highly performant environment.

      +
      +

      Accessing the database

      +

      Instructions on how to access the database can also be found in the generic guide.

      +
      +
      +
      +

      Deleting an EKS cluster

      +

      Once you are done with your experiments delete your cluster using the following command:

      +
      eksctl delete cluster "${CLUSTER_NAME}"
      +
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/exposing.html b/master/exposing.html new file mode 100644 index 00000000000..7620de9d044 --- /dev/null +++ b/master/exposing.html @@ -0,0 +1,897 @@ + + + + + + + + + + + + + Exposing ScyllaCluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Exposing ScyllaCluster

      +

      This document explains how ScyllaDB Operator exposes ScyllaClusters in different network setups. +A ScyllaCluster can be exposed in various network configurations, independently to clients and nodes.

      +
      +

      Note

      +

      ScyllaClusters can be only exposed when the ScyllaDB version used version is >=2023.1 ScyllaDB Enterprise or >=5.2 ScyllaDB Open Source.

      +
      +
      +

      Expose Options

      +

      exposeOptions specifies configuration options for exposing ScyllaCluster’s. +A ScyllaCluster created without any exposeOptions is equivalent to the following:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +     type: ClusterIP
      +    broadcastOptions:
      +      clients:
      +        type: ServiceClusterIP
      +      nodes:
      +        type: ServiceClusterIP
      +
      +
      +

      The following sections cover what every field controls and what the configuration options are.

      +
      +

      Node Service Template

      +

      nodeService serves as a template for a node-dedicated Service managed by the Scylla Operator for each node within a ScyllaCluster. +The properties of the Services depend on the selected type. +Additionally, there’s an option to define custom annotations, incorporated into each node’s Service, +which might be useful for further tweaking the Service properties or related objects.

      +
      +

      Headless Type

      +

      For Headless type, Scylla Operator creates a Headless Service with a selector pointing to the particular node in the ScyllaCluster. +Such Service doesn’t provide any additional IP addresses, and the internal DNS record resolves to the PodIP of a node.

      +

      This type of Service is useful when ScyllaCluster nodes broadcast PodIPs to clients and other nodes.

      +

      Example:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +     type: Headless
      +
      +
      +
      +
      +

      ClusterIP Type

      +

      For ClusterIP type, Scylla Operator creates a ClusterIP Service backed by a specific node in the ScyllaCluster.

      +

      These IP addresses are only routable within the same Kubernetes cluster, so it’s a good fit, if you don’t want to expose them to other networks.

      +

      Example:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +     type: ClusterIP
      +
      +
      +
      +
      +

      LoadBalancer Type

      +

      For the LoadBalancer type, Scylla Operator generates a LoadBalancer Service that directs traffic to a specific node within the ScyllaCluster. +On platforms with support for external load balancers, this Service provisions one. +The accessibility of this load balancer’s address depends on the platform and any customizations made; in some cases it may be reachable from the internal network or public Internet.

      +

      Customizations are usually managed via Service annotations, key-value pairs provided in annotations field are merged into each Service object. +LoadBalancer Services should be configured to pass through entire traffic.
      +For example, to expose LoadBalancer only to internal network use the following annotations:

      +
      + +
      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +     type: LoadBalancer
      +     annotations:
      +       service.beta.kubernetes.io/aws-load-balancer-scheme: internal
      +       service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
      +
      +
      +
      + +
      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +     type: LoadBalancer
      +     annotations:
      +       networking.gke.io/load-balancer-type: Internal
      +
      +
      +
      +
      +

      Check platform-specific documentation regarding LoadBalancer configuration to learn more about available options.

      +

      LoadBalancer Service is a superset of ClusterIP Service, implying that each LoadBalancer Service also contains an allocated ClusterIP. +They can be configured using the following fields, which propagate to every node Service:

      +
        +
      • externalTrafficPolicy

      • +
      • internalTrafficPolicy

      • +
      • loadBalancerClass

      • +
      • allocateLoadBalancerNodePorts

      • +
      +

      Check Kubernetes Service documentation to learn more about these options.

      +

      Example:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +     type: LoadBalancer
      +     loadBalancerClass: my-custom-load-balancer-class
      +
      +
      +
      +
      +
      +
      +

      Broadcast Options

      +

      Broadcast options control what is the source of the address being broadcasted to clients and nodes. +It’s configured independently for clients and nodes because you may want to expose these two types of traffic on different networks. +Using different networks can help manage costs, reliability, latency, security policies or other metrics you care about.

      +
      +

      PodIP Type

      +

      Address broadcasted to clients/nodes is taken from Pod. +By default, the address is taken from Pod’s status.PodIP field. +Because a Pod can use multiple address, you may want to provide source options by specifying podIP.source.

      +

      Example:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    broadcastOptions:
      +       clients:
      +         type: PodIP
      +         podIP:
      +           source: Status
      +
      +
      +
      +
      +

      ServiceClusterIP Type

      +

      Address broadcasted to clients or nodes is taken from spec.ClusterIP field of a node’s dedicated Service.

      +

      In order to configure it, the nodeService template must specify a Service having a ClusterIP assigned.

      +

      Example:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    broadcastOptions:
      +       clients:
      +         type: ServiceClusterIP
      +
      +
      +
      +
      +

      ServiceLoadBalancerIngress Type

      +

      Address broadcasted to clients/nodes is taken from the node dedicated Service, from status.ingress[0].ipAddress or status.ingress[0].hostname field.

      +

      In order to configure it, the nodeService template must specify the LoadBalancer Service.

      +

      Example:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    broadcastOptions:
      +       clients:
      +         type: ServiceLoadBalancerIngress
      +         podIP:
      +           source: Status
      +
      +
      +
      +
      +
      +
      +

      Deployment Examples

      +

      The following section contains several specific examples of various network scenarios and explains how nodes and clients communicate with one another.

      +
      +

      In-cluster only

      +

      ScyllaCluster definition:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +      type: ClusterIP
      +    broadcastOptions:
      +      clients:
      +        type: ServiceClusterIP
      +      nodes:
      +        type: ServiceClusterIP
      +
      +
      +

      Both client and nodes are deployed within the same Kubernetes cluster. +They talk through ClusterIP addresses taken from the Service. +Because ClusterIP Services are only routable within the same Kubernetes cluster, this cluster won’t be reachable from outside.

      +

      ClusterIPs

      +
      +
      +

      In-cluster node-to-node, VPC clients-to-nodes

      +

      ScyllaCluster definition:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +      type: ClusterIP
      +    broadcastOptions:
      +      clients:
      +        type: PodIP
      +      nodes:
      +        type: ServiceClusterIP
      +
      +
      +

      In this scenario, we assume that the Pod IP subnet is routable within a VPC. +Clients within the VPC network can communicate directly with ScyllaCluster nodes using PodIPs. +Nodes communicate with each other exclusively within the same Kubernetes cluster.

      +

      PodIPs

      +
      +
      +

      Multi VPC

      +

      ScyllaCluster definition:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +      type: Headless
      +    broadcastOptions:
      +      clients:
      +        type: PodIP
      +      nodes:
      +        type: PodIP
      +
      +
      +

      In this scenario, we set up two separate Kubernetes clusters in distinct VPCs. +These VPCs are interconnected to facilitate inter-VPC connectivity. +We operate on the assumption that the Pod IP subnet is routable within each VPC.

      +

      Both ScyllaClusters use the same exposeOptions, nodes broadcast their Pod IP addresses, enabling them to establish connections with one another. +****Check other documentation pages to know how to connect two ScyllaClusters into one logical cluster.

      +

      Clients, whether deployed within the same Kubernetes cluster or within a VPC, have the capability to reach nodes using their Pod IPs. +Since there is no requirement for any address other than the Pod IP, the Headless service type is sufficient.

      +

      MultiVPC

      +
      +
      +

      Internet

      +

      ScyllaCluster definition:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +      type: LoadBalancer
      +    broadcastOptions:
      +      clients:
      +        type: ServiceLoadBalancerIngress
      +      nodes:
      +        type: ClusterIP 
      +
      +
      +

      We assume that a Kubernetes cluster has been deployed in a cloud provider environment that supports external load balancers. +By specifying the LoadBalancer type in the nodeService template, the Scylla Operator generates a dedicated LB Service for each node. +The cloud provider then establishes an external load balancer with an internet-accessible address. +ScyllaDB nodes broadcast this external address to clients, enabling drivers to connect and discover other nodes. +Since all ScyllaDB nodes reside within the same Kubernetes cluster, there is no need to route traffic through the internet. +Consequently, the nodes are configured to communicate via ClusterIP, which is also accessible within LoadBalancer Services.

      +

      Internet

      +
      +

      Other more complex scenarios can be built upon these simple ones.

      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/generic.html b/master/generic.html new file mode 100644 index 00000000000..f3421dd9c4e --- /dev/null +++ b/master/generic.html @@ -0,0 +1,968 @@ + + + + + + + + + + + + + Deploying Scylla on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Deploying Scylla on a Kubernetes Cluster

      +

      This is a guide to deploy a Scylla Cluster in a generic Kubernetes environment, meaning that Scylla will not be deployed with the ideal performance. +Scylla performs the best when it has fast disks and direct access to the cpu. +This requires some extra setup, which is platform-specific. +For specific configuration and setup, check for details about your particular environment:

      + +
      +

      Prerequisites

      + +
      +
      +

      Running locally

      +

      Running kubernetes locally is a daunting and error prone task. +Fortunately there are ways to make life easier and Minikube makes it a breeze.

      +

      We need to give minikube a little bit more resources than default so start minikube like this:

      +
      minikube start --cpus=6
      +
      +
      +

      Then make kubectl aware of this local installation like this:

      +
      eval $(minikube docker-env)
      +
      +
      +
      +
      +

      Download Scylla Operator

      +

      In this guide you will be using the examples and manifests from Scylla Operator repository, so start off by cloning it to your local machine.

      +
      git clone git@github.com:scylladb/scylla-operator.git
      +cd scylla-operator
      +
      +
      +
      +
      +

      Deploy Cert Manager

      +

      First deploy Cert Manager, you can either follow upsteam instructions or use following command:

      +
      kubectl apply -f examples/common/cert-manager.yaml
      +
      +
      +

      This will install Cert Manager to provision a self-signed certificate.

      +

      Once it’s deployed, wait until Cert Manager is ready:

      +
      kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io
      +kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook
      +
      +
      +
      +
      +

      Deploy Scylla Operator

      +

      Deploy the Scylla Operator using the following commands:

      +
      kubectl apply -f deploy/operator.yaml
      +
      +
      +

      This will install the operator in namespace scylla-operator. +Wait until it’s ready:

      +
      kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
      +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
      +
      +
      +

      If you want to check the logs of the operator you can do so with:

      +
      kubectl -n scylla-operator logs deployment.apps/scylla-operator
      +
      +
      +
      +
      +

      Create and Initialize a Scylla Cluster

      +

      Now that the operator is running, we can create an instance of a Scylla cluster by creating an instance of the clusters.scylla.scylladb.com resource. +Some of that resource’s values are configurable, so feel free to browse cluster.yaml and tweak the settings to your liking. +Full details for all the configuration options can be found in the Scylla Cluster CRD documentation.

      +

      When you are ready to create a Scylla cluster, simply run:

      +
      kubectl create -f examples/generic/cluster.yaml
      +
      +
      +

      We can verify that a Kubernetes object has been created that represents our new Scylla cluster with the command below. +This is important because it shows that has successfully extended Kubernetes to make Scylla clusters a first class citizen in the Kubernetes cloud-native environment.

      +
      kubectl -n scylla get ScyllaCluster
      +
      +
      +

      Checking the pods that are created is as easy as:

      +
      kubectl -n scylla get pods
      +
      +
      +

      The output should be something like:

      +
      NAME                                    READY   STATUS    RESTARTS   AGE
      +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          9m49s
      +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          7m43s
      +simple-cluster-us-east-1-us-east-1a-2   2/2     Running   0          6m46s
      +
      +
      +

      It is important to note that the operator creates these instances according to a pattern. +This pattern is as follows: CLUSTER_NAME-DATACENTER_NAME-RACK_NAME-INSTANCE_NUMBER as specified in cluster.yaml.

      +

      In the above example we have the following properties:

      +
        +
      • CLUSTER_NAME: simple-cluster

      • +
      • DATACENTER_NAME: us-east-1

      • +
      • RACK_NAME: us-east-1a

      • +
      • INSTANCE_NUMBER: An automatically generated number attached to the pod name.

      • +
      +

      We picked the names to resemble something you can find in a cloud service but this is inconsequential, they can be set to anything you want.

      +

      To check if all the desired members are running, you should see the same number of entries from the following command as the number of members that was specified in cluster.yaml:

      +
      kubectl -n scylla get pod -l app=scylla
      +
      +
      +

      You can also track the state of a Scylla cluster from its status. To check the current status of a Cluster, run:

      +
      kubectl -n scylla describe ScyllaCluster simple-cluster
      +
      +
      +

      Checking the logs of the running scylla instances can be done like this:

      +
      kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 scylla
      +
      +
      +
      +

      Configure host networking

      +

      To squeeze the most out of your deployment it is sometimes necessary to employ host networking. +To enable this the CRD allows for specifying a network parameter as such:

      +
        version: 5.4.0
      +  agentVersion: 3.2.5
      +  cpuset: true
      +  network:
      +    hostNetworking: true
      +
      +
      +

      This will result in hosts network to be used for the Scylla Stateful Set deployment.

      +
      +
      +

      Configure container kernel parameters

      +

      Sometimes it is necessary to run the container with different kernel parameters. +In order to support this, the Scylla Operator defines a cluster property sysctls that is a list of the desired key-value pairs to set.

      +

      For example: To increase the number events available for asynchronous IO processing in the Linux kernel to N set sysctls tofs.aio-max-nr=N.

      +
      spec:
      +  sysctls:
      +  - "fs.aio-max-nr=2097152"
      +
      +
      +
      +
      +

      Deploying Alternator

      +

      The operator is also capable of deploying Alternator instead of the regular Scylla. +This requires a small change in the cluster definition. +Change the cluster.yaml file from this:

      +
      spec:
      +  agentVersion: 3.2.5
      +  version: 5.4.0
      +  developerMode: true
      +  datacenter:
      +    name: us-east-1
      +
      +
      +

      to this:

      +
      spec:
      +  version: 5.4.0
      +  alternator:
      +    port: 8000
      +    writeIsolation: only_rmw_uses_lwt
      +  agentVersion: 3.2.5
      +  developerMode: true
      +  datacenter:
      +    name: us-east-1
      +
      +
      +

      You can specify whichever port you want.

      +

      You must provide desired write isolation, supported values are: “always”, “forbid_rmw”, “only_rmw_uses_lwt”. +Difference between those isolation levels can be found in Scylla Alternator documentation.

      +

      Once this is done the regular CQL ports will no longer be available, the cluster is a pure Alternator cluster.

      +
      +
      +
      +

      Accessing the Database

      +
        +
      • From kubectl:

      • +
      +

      To get a cqlsh shell in your new Cluster:

      +
      kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- cqlsh
      +> DESCRIBE KEYSPACES;
      +
      +
      +
        +
      • From inside a Pod:

      • +
      +

      When you create a new Cluster, automatically creates a Service for the clients to use in order to access the Cluster. +The service’s name follows the convention <cluster-name>-client. +You can see this Service in your cluster by running:

      +
      kubectl -n scylla describe service simple-cluster-client
      +
      +
      +

      Pods running inside the Kubernetes cluster can use this Service to connect to Scylla. +Here’s an example using the Python Driver:

      +
      from cassandra.cluster import Cluster
      +
      +cluster = Cluster(['simple-cluster-client.scylla.svc'])
      +session = cluster.connect()
      +
      +
      +

      If you are running the Alternator you can access the API on the port you specified using plain http.

      +
      +
      +

      Configure Scylla

      +

      The operator can take a ConfigMap and apply it to the scylla.yaml configuration file. +This is done by adding a ConfigMap to Kubernetes and refering to this in the Rack specification. +The ConfigMap is just a file called scylla.yaml that has the properties you want to change in it. +The operator will take the default properties for the rest of the configuration.

      +
        +
      • Create a ConfigMap the default name that the operator uses is scylla-config:

      • +
      +
      kubectl create configmap scylla-config -n scylla --from-file=/path/to/scylla.yaml
      +
      +
      +
        +
      • Wait for the mount to propagate and then restart the cluster:

      • +
      +
      kubectl rollout restart -n scylla statefulset/simple-cluster-us-east-1-us-east-1a
      +
      +
      +
        +
      • The new config should be applied automatically by the operator, check the logs to be sure.

      • +
      +

      Configuring cassandra-rackdc.properties is done by adding the file to the same mount as scylla.yaml.

      +
      kubectl create configmap scylla-config -n scylla --from-file=/tmp/scylla.yaml --from-file=/tmp/cassandra-rackdc.properties -o yaml --dry-run | kubectl replace -f -
      +
      +
      +

      The operator will then apply the overridable properties prefer_local and dc_suffix if they are available in the provided mounted file.

      +
      +

      Note

      +

      If you want to enable authentication, you first need to adjust system_auth keyspace replication factor to the number of nodes in the datacenter via cqlsh. It allows you to ensure that the user’s information is kept highly available for the cluster. If system_auth is not equal to the number of nodes and a node fails, the user whose information is on that node will be denied access. +For production environments only use NetworkTopologyStrategy.

      +
      kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : <replication_factor>};"
      +
      +
      +

      You can read more about enabling authentication in the Enable authentication section of ScyllaDB’s documentation.

      +
      +
      +
      +

      Configure Scylla Manager Agent

      +

      The operator creates a second container for each scylla instance that runs Scylla Manager Agent. +This container serves as a sidecar and it’s the main endpoint for interacting with Scylla API. +The Scylla Manager Agent can be configured with various things such as the security token used to allow access to Scylla API and storage providers for backups.

      +

      To configure the agent you just create a new secret called scylla-agent-config-secret and populate it with the contents in the scylla-manager-agent.yaml file like this:

      +
      kubectl create secret -n scylla generic scylla-agent-config-secret --from-file scylla-manager-agent.yaml
      +
      +
      +

      See Scylla Manager Agent configuration for a complete reference of the Scylla Manager agent config file.

      +
      +

      Scylla Manager Agent auth token

      +

      Operator provisions Agent auth token by copying value from user provided config secret or auto generates it if it’s empty. +To check which value is being used, decode content of <cluster-name>-auth-token secret. +To change it simply remove the secret. Operator will create a new one. To pick up the change in the cluster, initiate a rolling restart.

      +
      +
      +
      +

      Set up monitoring

      +

      To set up monitoring using Prometheus and Grafana follow this guide.

      +
      +
      +

      Scale a ScyllaCluster

      +

      The operator supports adding new nodes to existing racks, adding new racks to the cluster, as well as removing both single nodes and entire racks. To introduce the changes, edit the cluster with:

      +
      kubectl -n scylla edit scyllaclusters.scylla.scylladb.com/simple-cluster
      +
      +
      +
        +
      • To modify the number of nodes in a rack, update the members field of the selected rack to a desired value.

      • +
      • To add a new rack, append it to the .spec.datacenter.racks list. Remember to choose a unique rack name for the new rack.

      • +
      • To remove a rack, first scale it down to zero nodes, and then remove it from .spec.datacenter.racks list.

      • +
      +

      Having edited and saved the yaml, you can check your cluster’s Status and Events to retrieve information about what’s happening:

      +
      kubectl -n scylla describe scyllaclusters.scylla.scylladb.com/simple-cluster
      +
      +
      +
      +

      Note

      +

      If you have configured ScyllaDB with authenticator set to PasswordAuthenticator, you need to manually configure the replication factor of the system_auth keyspace with every scaling operation.

      +
      kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -u <username> -p <password> -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : <new_replication_factor>};"
      +
      +
      +

      It is recommended to set system_auth replication factor to the number of nodes in each datacenter.

      +
      +
      +
      +

      Benchmark with cassandra-stress

      +

      After deploying our cluster along with the monitoring, we can benchmark it using cassandra-stress and see its performance in Grafana. We have a mini cli that generates Kubernetes Jobs that run cassandra-stress against a cluster.

      +
      +

      Because cassandra-stress doesn’t scale well to multiple cores, we use multiple jobs with a small core count for each

      +
      +
      # Run a benchmark with 10 jobs, with 6 cpus and 50.000.000 operations each.
      +# Each Job will throttle throughput to 30.000 ops/sec for a total of 300.000 ops/sec.
      +hack/cass-stress-gen.py --num-jobs=10 --cpu=6 --memory=20G --ops=50000000 --limit=30000
      +kubectl apply -f scripts/cassandra-stress.yaml
      +
      +
      +

      Make sure you set the proper arguments in case you have altered things such as name or namespace.

      +
      ./hack/cass-stress-gen.py -h
      +usage: cass-stress-gen.py [-h] [--num-jobs NUM_JOBS] [--name NAME] [--namespace NAMESPACE] [--scylla-version SCYLLA_VERSION] [--host HOST] [--cpu CPU] [--memory MEMORY] [--ops OPS] [--threads THREADS] [--limit LIMIT]
      +                          [--connections-per-host CONNECTIONS_PER_HOST] [--print-to-stdout] [--nodeselector NODESELECTOR]
      +
      +Generate cassandra-stress job templates for Kubernetes.
      +
      +optional arguments:
      +  -h, --help            show this help message and exit
      +  --num-jobs NUM_JOBS   number of Kubernetes jobs to generate - defaults to 1
      +  --name NAME           name of the generated yaml file - defaults to cassandra-stress
      +  --namespace NAMESPACE
      +                        namespace of the cassandra-stress jobs - defaults to "default"
      +  --scylla-version SCYLLA_VERSION
      +                        version of scylla server to use for cassandra-stress - defaults to 4.0.0
      +  --host HOST           ip or dns name of host to connect to - defaults to scylla-cluster-client.scylla.svc
      +  --cpu CPU             number of cpus that will be used for each job - defaults to 1
      +  --memory MEMORY       memory that will be used for each job in GB, ie 2G - defaults to 2G * cpu
      +  --ops OPS             number of operations for each job - defaults to 10000000
      +  --threads THREADS     number of threads used for each job - defaults to 50 * cpu
      +  --limit LIMIT         rate limit for each job - defaults to no rate-limiting
      +  --connections-per-host CONNECTIONS_PER_HOST
      +                        number of connections per host - defaults to number of cpus
      +  --print-to-stdout     print to stdout instead of writing to a file
      +  --nodeselector NODESELECTOR
      +                        nodeselector limits cassandra-stress pods to certain nodes. Use as a label selector, eg. --nodeselector role=scylla
      +
      +
      +

      While the benchmark is running, open up Grafana and take a look at the monitoring metrics.

      +

      After the Jobs finish, clean them up with:

      +
      kubectl delete -f scripts/cassandra-stress.yaml
      +
      +
      +
      +
      +

      Clean Up

      +

      To clean up all resources associated with this walk-through, you can run the commands below.

      +

      NOTE: this will destroy your database and delete all of its associated data.

      +
      kubectl delete -f examples/generic/cluster.yaml
      +kubectl delete -f deploy/operator.yaml
      +kubectl delete -f examples/common/cert-manager.yaml
      +
      +
      +
      +
      +

      Troubleshooting

      +

      If the cluster does not come up, the first step would be to examine the operator’s logs:

      +
      kubectl -n scylla-operator logs deployment.apps/scylla-operator
      +
      +
      +

      If everything looks OK in the operator logs, you can also look in the logs for one of the Scylla instances:

      +
      kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/genindex.html b/master/genindex.html new file mode 100644 index 00000000000..847beca1907 --- /dev/null +++ b/master/genindex.html @@ -0,0 +1,571 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + + + +
      + + + + + +
      + + +
      + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/gke.html b/master/gke.html new file mode 100644 index 00000000000..9d3eec4dd23 --- /dev/null +++ b/master/gke.html @@ -0,0 +1,790 @@ + + + + + + + + + + + + + Deploying Scylla on GKE | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Deploying Scylla on GKE

      +

      This guide is focused on deploying Scylla on GKE with maximum performance (without any persistence guarantees). +It sets up the kubelets on GKE nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

      +

      Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

      +
      +

      TL;DR;

      +

      If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

      +
      # Edit according to your preference
      +GCP_USER=$(gcloud config list account --format "value(core.account)")
      +GCP_PROJECT=$(gcloud config list project --format "value(core.project)")
      +GCP_ZONE=us-west1-b
      +
      +# From inside the examples/gke folder
      +cd examples/gke
      +./gke.sh -u "$GCP_USER" -p "$GCP_PROJECT" -z "$GCP_ZONE"
      +
      +# Example:
      +# ./gke.sh -u yanniszark@arrikto.com -p gke-demo-226716 -z us-west1-b
      +
      +
      +
      +

      Warning

      +

      Make sure to pass a ZONE (ex.: us-west1-b) and not a REGION (ex.: us-west1) or it will deploy nodes in each ZONE available in the region.

      +
      +

      After you deploy, see how you can benchmark your cluster with cassandra-stress.

      +
      +
      +

      Walkthrough

      +
      +

      Google Kubernetes Engine Setup

      +
      +

      Configure environment variables

      +

      First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

      +
      GCP_USER=$( gcloud config list account --format "value(core.account)" )
      +GCP_PROJECT=$( gcloud config list project --format "value(core.project)" )
      +GCP_REGION=us-west1
      +GCP_ZONE=us-west1-b
      +CLUSTER_NAME=scylla-demo
      +CLUSTER_VERSION=$( gcloud container get-server-config --zone ${GCP_ZONE} --format "value(validMasterVersions[0])" )
      +
      +
      +
      +
      +

      Creating a GKE cluster

      +

      First we need to change kubelet CPU Manager policy to static by providing a config file. Create file called systemconfig.yaml with the following content:

      +
      kubeletConfig:
      +  cpuManagerPolicy: static
      +
      +
      +

      Then we’ll create a GKE cluster with the following:

      +
        +
      1. A NodePool of 2 n1-standard-8 Nodes, where the operator and the monitoring stack will be deployed. These are generic Nodes and their free capacity can be used for other purposes.

        +
        gcloud container \
        +clusters create "${CLUSTER_NAME}" \
        +--cluster-version "${CLUSTER_VERSION}" \
        +--node-version "${CLUSTER_VERSION}" \
        +--machine-type "n1-standard-8" \
        +--num-nodes "2" \
        +--disk-type "pd-ssd" --disk-size "20" \
        +--image-type "UBUNTU_CONTAINERD" \
        +--enable-stackdriver-kubernetes \
        +--no-enable-autoupgrade \
        +--no-enable-autorepair
        +
        +
        +
      2. +
      3. A NodePool of 2 n1-standard-32 Nodes to deploy cassandra-stress later on.

        +
        gcloud container --project "${GCP_PROJECT}" \
        +node-pools create "cassandra-stress-pool" \
        +--cluster "${CLUSTER_NAME}" \
        +--zone "${GCP_ZONE}" \
        +--node-version "${CLUSTER_VERSION}" \
        +--machine-type "n1-standard-32" \
        +--num-nodes "2" \
        +--disk-type "pd-ssd" --disk-size "20" \
        +--node-taints role=cassandra-stress:NoSchedule \
        +--image-type "UBUNTU_CONTAINERD" \
        +--no-enable-autoupgrade \
        +--no-enable-autorepair
        +
        +
        +
      4. +
      5. A NodePool of 4 n1-standard-32 Nodes, where the Scylla Pods will be deployed. Each of these Nodes has 8 local NVMe SSDs attached, which are provided as raw block devices. It is important to disable autoupgrade and autorepair. Automatic cluster upgrade or node repair has a hard timeout after which it no longer respect PDBs and force deletes the Compute Engine instances, which also deletes all data on the local SSDs. At this point, it’s better to handle upgrades manually, with more control over the process and error handling.

        +
        gcloud container \
        +node-pools create "scylla-pool" \
        +--cluster "${CLUSTER_NAME}" \
        +--node-version "${CLUSTER_VERSION}" \
        +--machine-type "n1-standard-32" \
        +--num-nodes "4" \
        +--disk-type "pd-ssd" --disk-size "20" \
        +--local-nvme-ssd-block count="8" \
        +--node-taints role=scylla-clusters:NoSchedule \
        +--node-labels scylla.scylladb.com/node-type=scylla \
        +--image-type "UBUNTU_CONTAINERD" \
        +--system-config-from-file=systemconfig.yaml \
        +--no-enable-autoupgrade \
        +--no-enable-autorepair
        +
        +
        +
      6. +
      +
      +
      +

      Setting Yourself as cluster-admin

      +
      +

      (By default GKE doesn’t give you the necessary RBAC permissions)

      +
      +

      Get the credentials for your new cluster

      +
      gcloud container clusters get-credentials "${CLUSTER_NAME}" --zone="${GCP_ZONE}"
      +
      +
      +

      Create a ClusterRoleBinding for your user. +In order for this to work you need to have at least permission container.clusterRoleBindings.create. +The easiest way to obtain this permission is to enable the Kubernetes Engine Admin role for your user in the GCP IAM web interface.

      +
      kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user "${GCP_USER}"
      +
      +
      +
      +
      +
      +

      Prerequisites

      +
      +
      +

      Deploying ScyllaDB Operator

      +

      Refer to Deploying Scylla on a Kubernetes Cluster in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites.

      +
      +

      Setting up nodes for ScyllaDB

      +

      ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you’ll first need to form a RAID array from those disks. +NodeConfig performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in Performance tuning section of ScyllaDB Operator’s documentation.

      +

      Deploy NodeConfig to let it take care of the above operations:

      +
      kubectl apply --server-side -f examples/gke/nodeconfig-alpha.yaml
      +
      +
      +
      +
      +

      Deploying Local Volume Provisioner

      +

      Afterwards, deploy ScyllaDB’s Local Volume Provisioner, capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays.

      +
      kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/
      +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml
      +
      +
      +
      +
      +
      +

      Deploy Scylla cluster

      +

      In order for the example to work you need to modify the cluster definition in the following way:

      +
      sed -i "s/<gcp_region>/${GCP_REGION}/g;s/<gcp_zone>/${GCP_ZONE}/g" examples/gke/cluster.yaml
      +
      +
      +

      This will inject your region and zone into the cluster definition so that it matches the kubernetes cluster you just created.

      +
      +
      +

      Deploying ScyllaDB

      +

      Now you can follow the steps described in Deploying Scylla on a Kubernetes Cluster to launch your ScyllaDB cluster in a highly performant environment.

      +
      +

      Accessing the database

      +

      Instructions on how to access the database can also be found in the generic guide.

      +
      +
      +
      +

      Deleting a GKE cluster

      +

      Once you are done with your experiments delete your cluster using the following command:

      +
      gcloud container --project "${GCP_PROJECT}" clusters delete --zone "${GCP_ZONE}" "${CLUSTER_NAME}"
      +
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/helm.html b/master/helm.html new file mode 100644 index 00000000000..6dc05d2d933 --- /dev/null +++ b/master/helm.html @@ -0,0 +1,938 @@ + + + + + + + + + + + + + Deploying Scylla stack using Helm Charts | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Deploying Scylla stack using Helm Charts

      +

      In this example we will install Scylla stack on Kubernetes. This includes the following components:

      +
        +
      • Scylla Operator

      • +
      • Scylla Manager

      • +
      • Scylla

      • +
      +

      We will use Minikube K8s cluster, but this could be any K8s cluster supported by the Scylla Operator.

      +
      +

      Prerequisites

      +
        +
      • Kubernetes 1.16+

      • +
      • Helm 3+

      • +
      +
      +
      +

      TL;DR

      +
      helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
      +helm repo update
      +kubectl apply -f examples/common/cert-manager.yaml 
      +helm install scylla-operator scylla/scylla-operator --create-namespace --namespace scylla-operator
      +helm install scylla-manager scylla/scylla-manager --create-namespace --namespace scylla-manager
      +helm install scylla scylla/scylla --create-namespace --namespace scylla
      +
      +
      +
      +
      +

      Deploy Cert Manager

      +

      This step is optional if you want to use your own certificate. +If you don’t have one, make sure to not disable autogeneration using Scylla Operator Helm Chart.

      +

      First deploy Cert Manager, you can either follow upsteam instructions or use following command:

      +
      kubectl apply -f examples/common/cert-manager.yaml
      +
      +
      +

      Once it’s deployed, wait until all Cert Manager pods will enter into Running state:

      +
      kubectl wait -n cert-manager --for=condition=ready pod -l app=cert-manager --timeout=60s
      +
      +
      +
      +
      +

      Helm Chart repository

      +

      To install Scylla Helm Chart repository execute the following commands:

      +
      helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
      +helm repo update
      +
      +
      +

      Then you can search through repository, it should contain at least three Helm charts:

      +
      helm search repo scylla
      +NAME                   CHART VERSION   APP VERSION     DESCRIPTION                                       
      +scylla/scylla          1.0.1           v1.0.1          Scylla is a close-to-the-hardware rewrite of Ca...
      +scylla/scylla-manager  1.0.1           v1.0.1          Scylla Manager automates database operations.     
      +scylla/scylla-operator 1.0.1           v1.0.1          Scylla Operator is a Kubernetes Operator for ma...
      +
      +
      +

      All these charts should be installable without any need of customizing (defaults are provided). +Although Helm is used for this particular reason, so lets customize them a bit.

      +
      +
      +

      Scylla Operator Chart

      +

      This chart is very simple, most interesting customizable fields are image, resources and webhook. +All others can be looked up in Chart source in Scylla Operator repository.

      +
      +

      image

      +

      Image allows to define which Scylla Operator image will be used. By default it downloads the image from main +Docker Hub repository, using version defined in Helm Chart. +You can also change pullPolicy if default one does not +fullfill your needs. In Kubernetes documentation you +can read more about different pull policies.

      +

      Image URL will be composed based on these fields in follwing pattern: +repository/scylla-operator:tag

      +
      image:
      +  repository: scylladb
      +  pullPolicy: IfNotPresent
      +  tag: ""
      +
      +
      +
      +
      +

      resources

      +

      You can customize how much resources will be allocated for Operator pods via resource field:

      +
      resources:
      +  limits:
      +    cpu: 100m
      +    memory: 128Mi
      +  requests:
      +    cpu: 100m
      +    memory: 32Mi
      +
      +
      +

      To read more about resource specification, follow Kubernetes documentation.

      +
      +
      +

      webhook

      +

      Webhook field allows to decide whether you want to use autogenerated self-signed certificate using Cert Manager or +whether you want to provide your own certificate.

      +

      createSelfSignedCertificate specifies whether a self-signed certificate should be created using Cert Manager +certificateSecretName: name of a secret containing custom certificate.

      +
      webhook:
      +  createSelfSignedCertificate: true
      +  certificateSecretName: ""
      +
      +
      +
      +
      +

      Customization

      +

      You can customize all these fields and others by providing file containing desired values. +Content of this file will overwrite default values.

      +

      You can find an example in Scylla Operator repository under examples/helm/values.operator.yaml

      +
      +
      +

      Installation

      +

      To deploy Scylla Operator using customized values file execute the following:

      +
      helm install scylla-operator scylla/scylla-operator --values examples/helm/values.operator.yaml --create-namespace --namespace scylla-operator
      +
      +
      +
      +
      +
      +

      Scylla Helm Chart

      +

      Scylla Chart allows to customize and deploy Scylla cluster. +By default Scylla Helm charts deploys working Scylla cluster, but of course we can customize it.

      +
      +

      Customization

      +

      Versions of images used in the cluster can be set via scyllaImage and agentImage

      +
      scyllaImage:
      +  repository: scylladb/scylla
      +  tag: 4.3.0
      +
      +agentImage:
      +  repository: scylladb/scylla-manager-agent
      +  tag: 2.2.1
      +
      +
      +

      A minimal Scylla cluster can be expressed as:

      +
      datacenter: us-east-1
      +racks:
      +- name: us-east-1b
      +  members: 2
      +  storage:
      +    capacity: 5G
      +  resources:
      +    limits:
      +      cpu: 1
      +      memory: 1Gi
      +    requests:
      +      cpu: 1
      +      memory: 1Gi
      +
      +
      +

      Above cluster will use 4.3.0 Scylla, 2.2.1 Scylla Manager Agent sidecar and will have a single rack having 2 nodes. +Each node will have a single CPU and 1 GiB of memory.

      +

      For other customizable fields, please refer to ScyllaCluster CRD. +CRD Rack Spec and Helm Chart Rack should have the same fields.

      +
      +
      +

      Installation

      +

      To deploy Scylla cluster using customzied values file execute the following command:

      +
      helm install scylla scylla/scylla --values examples/helm/values.cluster.yaml --create-namespace --namespace scylla
      +
      +
      +

      Scylla Operator will provision this cluster on your K8s environment.

      +
      +
      +
      +

      Scylla Manager Helm Chart

      +

      Scylla Manager Chart allows to customize and deploy Scylla Manager in K8s environment. +Scylla Manager consist of two applications (Scylla Manager itself and Scylla Manager Controller) and additional Scylla cluster.

      +

      To read more about Scylla Manager see Manager guide.

      +
      +

      Scylla Manager

      +

      To set version of used Scylla Manager you can use image field:

      +
      image:
      +  repository: scylladb
      +  pullPolicy: IfNotPresent
      +  tag: 2.2.1
      +
      +
      +

      To control how many resources are allocated for Scylla Manager use resource field:

      +
      resources:
      +  limits:
      +    cpu: 500m
      +    memory: 500Mi
      +  requests:
      +    cpu: 500m
      +    memory: 500Mi
      +
      +
      +
      +
      +

      Scylla Manager Controller

      +

      Similarly Scylla Manager Controller image can be customized:

      +
      controllerImage:
      +  repository: scylladb
      +  pullPolicy: IfNotPresent
      +  tag: ""
      +
      +
      +

      And allocated resources:

      +
      controllerResources:
      +  limits:
      +    cpu: 100m
      +    memory: 30Mi
      +  requests:
      +    cpu: 100m
      +    memory: 20Mi
      +
      +
      +
      +
      +

      Scylla

      +

      To customize internal Scylla instance dedicated to Scylla Manager, see guide above customizing Scylla Helm Chart. +It’s definition should land as a scylla field.

      +
      +
      +

      Customization

      +

      All others customizable fields can be looked up in Chart source in Scylla Operator repository.

      +
      +
      +

      Installation

      +

      To deploy Scylla Manager using customized values file execute the following command:

      +
      helm install scylla-manager scylla/scylla-manager --values examples/helm/values.manager.yaml --create-namespace --namespace scylla-manager
      +
      +
      +
      +
      +
      +
      +

      Results

      +

      Scylla need some time to bootstrap all nodes, but after some time you should be ready to roll. It was simple isn’t it? +You can validate if everything was set up correctly by looking at the all resources created in used namespaces.

      +

      Scylla Operator:

      +
      $ kubectl -n scylla-operator get all
      +
      +NAME                                   READY   STATUS    RESTARTS   AGE
      +pod/scylla-operator-5dbcb54f5c-vjm4m   1/1     Running   0          51s
      +pod/scylla-operator-5dbcb54f5c-wfjbw   1/1     Running   0          51s
      +
      +NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
      +service/scylla-operator-webhook   ClusterIP   10.105.207.130   <none>        443/TCP   51s
      +
      +NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
      +deployment.apps/scylla-operator   2/2     2            2           51s
      +
      +NAME                                         DESIRED   CURRENT   READY   AGE
      +replicaset.apps/scylla-operator-5dbcb54f5c   2         2         2       51s
      +
      +
      +

      Operator is running!

      +

      Scylla Manager:

      +
      $ kubectl -n scylla-manager get all 
      +
      +NAME                                             READY   STATUS    RESTARTS   AGE
      +pod/scylla-manager-669db64dd-bcm4v               1/1     Running   0          89s
      +pod/scylla-manager-controller-844ccc56c4-drbth   1/1     Running   0          89s
      +pod/scylla-manager-controller-844ccc56c4-rhwqx   1/1     Running   0          89s
      +
      +NAME                            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
      +service/scylla-manager          ClusterIP   10.105.231.53   <none>        80/TCP,5090/TCP     89s
      +service/scylla-manager-client   ClusterIP   None            <none>        9180/TCP,5090/TCP   89s
      +
      +NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
      +deployment.apps/scylla-manager              1/1     1            1           89s
      +deployment.apps/scylla-manager-controller   2/2     2            2           89s
      +
      +NAME                                                   DESIRED   CURRENT   READY   AGE
      +replicaset.apps/scylla-manager-669db64dd               1         1         1       89s
      +replicaset.apps/scylla-manager-controller-844ccc56c4   2         2         2       89s
      +
      +
      +

      Good to go, ready to serve!

      +

      Scylla itself:

      +
      $ kubectl -n scylla get all        
      +
      +NAME                                READY   STATUS    RESTARTS   AGE
      +pod/scylla-us-east-1-us-east-1b-0   2/2     Running   0          5m58s
      +pod/scylla-us-east-1-us-east-1b-1   2/2     Running   0          4m29s
      +
      +NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
      +service/scylla-client                   ClusterIP   None           <none>        9180/TCP,5090/TCP                                                 5m59s
      +service/scylla-us-east-1-us-east-1b-0   ClusterIP   10.43.149.92   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   5m58s
      +service/scylla-us-east-1-us-east-1b-1   ClusterIP   10.43.49.0     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   4m29s
      +
      +NAME                                           READY   AGE
      +statefulset.apps/scylla-us-east-1-us-east-1b   2/2     5m59s
      +
      +
      +

      Two running nodes, exactly what we were asking for.

      +
      +
      +

      Monitoring

      +

      To spin up a Prometheus monitoring refer to monitoring guide.

      +

      Helm charts can create ServiceMonitors needed to observe Scylla Manager and Scylla. +Both of these Helm Charts allows to specify whether you want to create a ServiceMonitor:

      +
      serviceMonitor:
      +  create: false
      +
      +
      +

      Change create to true and update your current deployment using:

      +
      helm upgrade --install scylla --namespace scylla scylla/scylla -f examples/helm/values.cluster.yaml
      +
      +
      +

      Helm should notice the difference, install the ServiceMonitor, and then Prometheous will be able to scrape metrics.

      +
      +
      +

      Cleanup

      +

      To remove these applications you can simply uninstall them using Helm CLI:

      +
      helm uninstall scylla -n scylla
      +helm uninstall scylla-manager -n scylla-manager
      +helm uninstall scylla-operator -n scylla-operator
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/index.html b/master/index.html new file mode 100644 index 00000000000..121a1212593 --- /dev/null +++ b/master/index.html @@ -0,0 +1,618 @@ + + + + + + + + + + + + + Scylla Operator Documentation | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Scylla Operator Documentation

      +
      +
      +

      Scylla Operator is an open source project which helps users of Scylla Open Source and Scylla Enterprise run Scylla on Kubernetes (K8s) +The Scylla operator manages Scylla clusters deployed to Kubernetes and automates tasks related to operating a Scylla cluster, like installation, out and downscale, rolling upgrades.

      +_images/logo.png +

      For the latest status of the project, and reports issue, see the Github Project. Also check out the K8s Operator lesson on Scylla University.

      +

      scylla-operator is a Kubernetes Operator for managing Scylla clusters.

      +

      Currently it supports:

      +
        +
      • Deploying multi-zone clusters

      • +
      • Scaling up or adding new racks

      • +
      • Scaling down

      • +
      • Monitoring with Prometheus and Grafana

      • +
      • Integration with Scylla Manager

      • +
      • Dead node replacement

      • +
      • Version Upgrade

      • +
      • Backup

      • +
      • Repairs

      • +
      • Autohealing

      • +
      +

      Choose a topic to begin:

      + +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/manager.html b/master/manager.html new file mode 100644 index 00000000000..5a88904d868 --- /dev/null +++ b/master/manager.html @@ -0,0 +1,825 @@ + + + + + + + + + + + + + Deploying Scylla Manager on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Deploying Scylla Manager on a Kubernetes Cluster

      +

      Scylla Manager is a product for database operations automation, +it can schedule tasks such as repairs and backups. +Scylla Manager can manage multiple Scylla clusters and run cluster-wide tasks +in a controlled and predictable way.

      +

      Scylla Manager is available for Scylla Enterprise customers and Scylla Open Source users. +With Scylla Open Source, Scylla Manager is limited to 5 nodes. +See the Scylla Manager Proprietary Software License Agreement for details.

      +
      +

      Prerequisites

      + +
      +
      +

      Architecture

      +

      Scylla Manager in K8s consist of:

      +
        +
      • Dedicated Scylla Cluster

        +

        Scylla Manager persists its state to a Scylla cluster. +Additional small single node cluster is spawned in the Manager namespace.

        +
      • +
      • Scylla Manager Controller

        +

        Main mission of Controller is to watch changes of Scylla Clusters, and synchronize three states.

        +
          +
        1. What user wants - task definition in CRD.

        2. +
        3. What Controller registered - Task name to Task ID mapping - CRD status.

        4. +
        5. Scylla Manager task listing - internal state of Scylla Manager.

        6. +
        +

        When Scylla Cluster CRD is being deployed Controller will register it in Scylla Manager once cluster reaches desired node count. +Once Cluster is fully up and running it will schedule all tasks defined in Cluster CRD. +Controller also supports task updates and unscheduling.

        +
      • +
      • Scylla Manager

        +

        Regular Scylla Manager, the same used in cloud and bare metal deployments.

        +
      • +
      +
      +
      +

      Deploy Scylla Manager

      +

      Deploy the Scylla Manager using the following commands:

      +
      kubectl apply -f deploy/manager-prod.yaml
      +
      +
      +

      This will install the Scylla Manager in the scylla-manager namespace. +You can check if the Scylla Manager is up and running with:

      +
      kubectl -n scylla-manager get pods
      +NAME                                               READY   STATUS    RESTARTS   AGE
      +scylla-manager-cluster-manager-dc-manager-rack-0   2/2     Running   0          37m
      +scylla-manager-controller-0                        1/1     Running   0          28m
      +scylla-manager-scylla-manager-7bd9f968b9-w25jw     1/1     Running   0          37m
      +
      +
      +

      As you can see there are three pods:

      +
        +
      • scylla-manager-cluster-manager-dc-manager-rack-0 - is a single node Scylla cluster.

      • +
      • scylla-manager-controller-0 - Scylla Manager Controller.

      • +
      • scylla-manager-scylla-manager-7bd9f968b9-w25jw - Scylla Manager.

      • +
      +

      To see if Scylla Manager is fully up and running we can check their logs. +To do this, execute following command:

      +
      kubectl -n scylla-manager logs scylla-manager-controller-0
      +
      +
      +

      The output should be something like:

      +
      {"L":"INFO","T":"2020-09-23T11:25:27.882Z","M":"Scylla Manager Controller started","version":"","build_date":"","commit":"","built_by":"","go_version":"","options":{"Name":"scylla-manager-controller-0","Namespace":"scylla-manager","LogLevel":"debug","ApiAddress":"http://127.0.0.1:5080/api/v1"},"_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
      +{"L":"INFO","T":"2020-09-23T11:25:28.435Z","M":"Registering Components.","_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
      +
      +
      +

      To check logs of Scylla Manager itself, use following command:

      +
      kubectl -n scylla-manager logs scylla-manager-scylla-manager-7bd9f968b9-w25jw
      +
      +
      +

      The output should be something like:

      +
      {"L":"INFO","T":"2020-09-23T11:26:53.238Z","M":"Scylla Manager Server","version":"2.1.2-0.20200816.76cc4dcc","pid":1,"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
      +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Using config","config":{"HTTP":"127.0.0.1:5080","HTTPS":"","TLSCertFile":"/var/lib/scylla-manager/scylla_manager.crt","TLSKeyFile":"/var/lib/scylla-manager/scylla_manager.key","TLSCAFile":"","Prometheus":":56090","PrometheusScrapeInterval":5000000000,"debug":"127.0.0.1:56112","Logger":{"Mode":"stderr","Level":"info","Development":false},"Database":{"Hosts":["scylla-manager-cluster-manager-dc-manager-rack-0.scylla-manager.svc"],"SSL":false,"User":"","Password":"","LocalDC":"","Keyspace":"scylla_manager","MigrateDir":"/etc/scylla-manager/cql","MigrateTimeout":30000000000,"MigrateMaxWaitSchemaAgreement":300000000000,"ReplicationFactor":1,"Timeout":600000000,"TokenAware":true},"SSL":{"CertFile":"","Validate":true,"UserCertFile":"","UserKeyFile":""},"Healthcheck":{"Timeout":250000000,"SSLTimeout":750000000},"Backup":{"DiskSpaceFreeMinPercent":10,"AgeMax":43200000000000},"Repair":{"SegmentsPerRepair":1,"ShardParallelMax":0,"ShardFailedSegmentsMax":100,"PollInterval":200000000,"ErrorBackoff":300000000000,"AgeMax":0,"ShardingIgnoreMsbBits":12}},"config_files":["/mnt/etc/scylla-manager/scylla-manager.yaml"],"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
      +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Checking database connectivity...","_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
      +
      +
      +

      If there are no errors in the logs, let’s spin a Scylla Cluster.

      +
      +
      +

      Cluster registration

      +

      When the Scylla Manager is fully up and running, lets create a regular instance of Scylla cluster.

      +

      See generic tutorial to spawn your cluster.

      +

      Note: If you already have some Scylla Clusters, after installing Manager they should be +automatically registered in Scylla Manager.

      +

      Once cluster reaches desired node count, cluster status will be updated with ID under which it was registered in Manager.

      +
      kubectl -n scylla describe Cluster
      +
      +[...]
      +Status:
      + Manager Id:  d1d532cd-49f2-4c97-9263-25126532803b
      + Racks:
      +   us-east-1a:
      +     Members:        3
      +     Ready Members:  3
      +     Version:        4.0.0
      +
      +
      +

      You can use this ID to talk to Scylla Manager using sctool CLI installed in Scylla Manager Pod. +You can also use Cluster name in namespace/cluster-name format.

      +
      kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
      +
      +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
      +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
      +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
      +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
      +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
      +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
      +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
      +
      +
      +

      Scylla Manager by default registers recurring healhcheck tasks for Agent and for each of the enabled frontends (CQL, Alternator).

      +

      In this task listing we can see CQL and REST healthchecks.

      +
      +
      +

      Task scheduling

      +

      You can either define tasks prior Cluster creation, or for existing Cluster. +Let’s edit already running cluster definition to add repair and backup task.

      +
      kubectl -n scylla edit Cluster simple-cluster
      +
      +
      +

      Add following task definition to Cluster spec:

      +
        repairs:
      +    - name: "users repair"
      +      keyspace: ["users"]
      +      interval: "1d"
      +  backups:
      +    - name: "weekly backup"
      +      location: ["s3:cluster-backups"]
      +      retention: 3
      +      interval: "7d"
      +    - name: "daily backup"
      +      location: ["s3:cluster-backups"]
      +      retention: 7
      +      interval: "1d"
      +
      +
      +

      For full task definition configuration consult ScyllaCluster CRD.

      +

      Note: Scylla Manager Agent must have access to above bucket prior the update in order to schedule backup task. +Consult Scylla Manager documentation for details on how to set it up.

      +

      Scylla Manager Controller will spot this change and will schedule tasks in Scylla Manager.

      +
      kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
      +
      +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
      +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
      +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
      +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
      +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
      +│ backup/275aae7f-c436-4fc8-bcec-479e65fb8372                 │ -L s3:cluster-backups  --retention 3 │ 23 Sep 20 14:28:58 CEST (+7d)  │ NEW    │
      +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
      +│ repair/d4946360-c29d-4bb4-8b9d-619ada495c2a                 │                                      │ 23 Sep 20 14:38:42 CEST        │ NEW    │
      +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
      +
      +
      +

      As you can see, we have two new tasks, weekly recurring backup, and one repair which should start shortly.

      +

      To check progress of run you can use following command:

      +
      kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task progress --cluster d1d532cd-49f2-4c97-9263-25126532803b repair/d4946360-c29d-4bb4-8b9d-619ada495c2a
      +Status:         RUNNING
      +Start time:     23 Sep 20 14:38:42 UTC
      +Duration:       13s
      +Progress:       2.69%
      +Datacenters:
      +  - us-east-1
      ++--------------------+-------+
      +| system_auth        | 8.06% |
      +| system_distributed | 0.00% |
      +| system_traces      | 0.00% |
      ++--------------------+-------+
      +
      +
      +

      Other tasks can be also tracked using the same command, but using different task ID. +Task IDs are present in Cluster Status as well as in task listing.

      +
      +
      +

      Clean Up

      +

      To clean up all resources associated with Scylla Manager, you can run the commands below.

      +

      NOTE: this will destroy your Scylla Manager database and delete all of its associated data.

      +
      kubectl delete -f deploy/manager-prod.yaml
      +
      +
      +
      +
      +

      Troubleshooting

      +

      Manager is not running

      +

      If the Scylla Manager does not come up, the first step would be to examine the Manager and Controller logs:

      +
      kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-controller
      +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-scylla-manager-7bd9f968b9-w25jw
      +
      +
      +

      My task wasn’t scheduled

      +

      If your task wasn’t scheduled, Cluster status will be updated with error messages for each failed task. +You can also consult Scylla Manager logs.

      +

      Example:

      +

      Following status describes error when backup task cannot be scheduled, due to lack of access to bucket:

      +
      Status:
      +  Backups:
      +    Error:     create backup target: location is not accessible: 10.100.16.62: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.100.16.62 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.107.193.33: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.107.193.33 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.109.197.60: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.109.197.60 and run "scylla-manager-agent check-location -L s3:manager-test --debug"
      +    Id:        00000000-0000-0000-0000-000000000000
      +    Interval:  0
      +    Location:
      +      s3:manager-test
      +    Name:         adhoc backup
      +    Num Retries:  3
      +    Retention:    3
      +    Start Date:   now
      +  Manager Id:     2b9dbe8c-9daa-4703-a66d-c29f63a917c8
      +  Racks:
      +    us-east-1a:
      +      Members:        3
      +      Ready Members:  3
      +      Version:        4.0.0
      +
      +
      +

      Because Controller is infinitely retrying to schedule each defined task, once permission issues will be resolved, +task should appear in task listing and Cluster status.

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/migration.html b/master/migration.html new file mode 100644 index 00000000000..394fbed3319 --- /dev/null +++ b/master/migration.html @@ -0,0 +1,762 @@ + + + + + + + + + + + + + Version migrations | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Version migrations

      +
      +

      v0.3.0 -> v1.0.0 migration

      +

      v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common kind +which is easier to disambiguate (ScyllaCluster). +This change is backward incompatible, which means manual migration is needed.

      +

      This procedure involves having two CRDs registered at the same time. We will detach Scylla Pods +from Scylla Operator for a short period to ensure that nothing is garbage collected when Scylla Operator is upgraded. +Compared to the upgrade guide where full deletion is requested, this procedure shouldn’t cause downtimes. +Although detaching resources from their controller is considered hacky. This means that you shouldn’t run procedure +out of the box on production. Make sure this procedure works well multiple times on your staging environment first.

      +

      Read the whole procedure and make sure you understand what is going on before executing any of the commands!

      +

      In case of any issues or questions regarding this procedure, you’re welcomed on our Scylla Users Slack +on #kubernetes channel.

      +
      +
      +

      Procedure

      +
        +
      1. Execute this whole procedure for each cluster sequentially. To get a list of existing clusters execute the following

        +
        kubectl -n scylla get cluster.scylla.scylladb.com
        +
        +NAME             AGE
        +simple-cluster   30m
        +
        +
        +

        All below commands will use scylla namespace and simple-cluster as a cluster name.

        +
      2. +
      3. Make sure you’re using v1.0.0 tag:

        +
        git checkout v1.0.0
        +
        +
        +
      4. +
      5. Upgrade your cert-manager to v1.0.0. If you installed it from a static file from this repo, simply execute the following:

        +
         kubectl apply -f examples/common/cert-manager.yaml
        +
        +
        +

        If your cert-manager was installed in another way, follow official instructions on cert-manager website.

        +
      6. +
      7. deploy/operator.yaml file contains multiple resources. Extract only CustomResourceDefinition to separate file.

      8. +
      9. Install v1.0.0 CRD definition from file created in the previous step:

        +
        kubectl apply -f examples/common/crd.yaml
        +
        +
        +
      10. +
      11. Save your existing simple-cluster Cluster definition to a file:

        +
        kubectl -n scylla get cluster.scylla.scylladb.com simple-cluster -o yaml > existing-cluster.yaml
        +
        +
        +
      12. +
      13. Migrate Kind and ApiVersion to new values using:

        +
        sed -i 's/scylla.scylladb.com\/v1alpha1/scylla.scylladb.com\/v1/g' existing-cluster.yaml
        +sed -i 's/kind: Cluster/kind: ScyllaCluster/g' existing-cluster.yaml
        +
        +
        +
      14. +
      15. Install migrated CRD instance

        +
        kubectl apply -f existing-cluster.yaml
        +
        +
        +

        At this point, we should have two CRDs describing your Scylla cluster, although the new one is not controlled by the Operator.

        +
      16. +
      17. Get UUID of newly created ScyllaCluster resource:

        +
        kubectl -n scylla get ScyllaCluster simple-cluster --template="{{ .metadata.uid }}"
        +
        +12a3678d-8511-4c9c-8a48-fa78d3992694
        +
        +
        +

        Save output UUID somewhere, it will be referred as <new-cluster-uid> in commands below.

        +

        Depending on your shell, you might get additional ‘%’ sign at the end of UUID, make sure to remove it!

        +
      18. +
      19. Upgrade ClusterRole attached to each of the Scylla nodes to grant them permission to lookup Scylla clusters:

        +
        kubectl patch ClusterRole simple-cluster-member --type "json" -p '[{"op":"add","path":"/rules/-","value":{"apiGroups":["scylla.scylladb.com"],"resources":["scyllaclusters"],"verbs":["get"]}}]'
        +
        +
        +

        Amend role name according to your cluster name, it should look like <scylla-cluster-name>-member.

        +
      20. +
      21. Get a list of all Services associated with your cluster. First get list of all services:

        +
         kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
        +
        + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
        + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          109m
        + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
        + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   108m
        + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   106m
        +
        +
        +
        +
      22. +
      23. For each service, change its ownerReference to point to new CRD instance:

        +
         kubectl -n scylla patch svc <cluster-svc-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
        +
        +
        +

        Replace <cluster-svc-name> with Service name, and <new-cluster-uid> with saved UUID from one of the previous steps.

        +
      24. +
      25. Get a list of all Services again to see if none was deleted. Check also “Age” column, it shouldn’t be lower than previous result.

        +
         kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
        +
        + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
        + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          110m
        + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   110m
        + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
        + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   107m
        +
        +
        +
        +
      26. +
      27. Get a list of StatefulSets associated with your cluster:

        +
        kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
        +
        +NAME                                  READY   AGE
        +simple-cluster-us-east-1-us-east-1a   3/3     104m
        +
        +
        +
      28. +
      29. For each StatefulSet from previous step, change its ownerReference to point to new CRD instance.

        +
         kubectl -n scylla patch sts <cluster-sts-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
        +
        +
        +

        Replace <cluster-sts-name> with StatefulSet name, and <new-cluster-uid> with saved UUID from one of the previous steps.

        +
      30. +
      31. Now when all k8s resources bound to Scylla are attached to new CRD, we can remove 0.3.0 Operator and old CRD definition. +Checkout v0.3.0 version, and remove Scylla Operator, and old CRD:

        +
         git checkout v0.3.0
        + kubectl delete -f examples/generic/operator.yaml
        +
        +
        +
      32. +
      33. Checkout v1.0.0, and install upgraded Scylla Operator:

        +
         git checkout v1.0.0
        + kubectl apply -f deploy/operator.yaml
        +
        +
        +
      34. +
      35. Wait until Scylla Operator boots up:

        +
         kubectl -n scylla-operator-system wait --for=condition=ready pod --all --timeout=600s
        +
        +
        +
      36. +
      37. Get a list of StatefulSets associated with your cluster:

        +
        kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
        +
        +NAME                                  READY   AGE
        +simple-cluster-us-east-1-us-east-1a   3/3     104m
        +
        +
        +
      38. +
      39. For each StatefulSet from previous step, change its sidecar container image to v1.0.0, and wait until change will be propagated. This step will initiate a rolling restart of pods one by one.

        +
        kubectl -n scylla patch sts <cluster-sts> --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/initContainers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
        +kubectl -n scylla rollout status sts <cluster-sts>
        +
        +
        +

        Replace <cluster-sts-name> with StatefulSet name.

        +
      40. +
      41. If you’re using Scylla Manager, bump Scylla Manager Controller image to v1.0.0

        +
         kubectl -n scylla-manager-system patch sts scylla-manager-controller --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
        +
        +
        +
      42. +
      43. Your Scylla cluster is now migrated to v1.0.0.

      44. +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/monitoring.html b/master/monitoring.html new file mode 100644 index 00000000000..a3f3ec4ddda --- /dev/null +++ b/master/monitoring.html @@ -0,0 +1,807 @@ + + + + + + + + + + + + + Monitoring | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Monitoring

      +

      Scylla Operator 1.8 introduced a new API resource ScyllaDBMonitoring, allowing users to deploy a managed monitoring +setup for their Scylla Clusters.

      +
      apiVersion: scylla.scylladb.com/v1alpha1
      +kind: ScyllaDBMonitoring
      +metadata:
      +  name: example
      +spec:
      +  type: Platform
      +  endpointsSelector:
      +    matchLabels:
      +      app.kubernetes.io/name: scylla
      +      scylla-operator.scylladb.com/scylla-service-type: member
      +      scylla/cluster: replace-with-your-scyllacluster-name
      +  components:
      +    prometheus:
      +      storage:
      +        volumeClaimTemplate:
      +          spec:
      +            resources:
      +              requests:
      +                storage: 1Gi
      +    grafana:
      +      exposeOptions:
      +        webInterface:
      +          ingress:
      +            ingressClassName: haproxy
      +            dnsDomains:
      +            - test-grafana.test.svc.cluster.local
      +            annotations:
      +              haproxy-ingress.github.io/ssl-passthrough: "true"
      +
      +
      +

      For details, refer to the below command:

      +
      $ kubectl explain scylladbmonitorings.scylla.scylladb.com/v1alpha1
      +
      +
      +
      +

      Deploy managed monitoring

      +

      Note: as of v1.8, ScyllaDBMonitoring is experimental. The API is currently in version v1alpha1 and may change in future versions.

      +
      +

      Requirements

      +

      Before you can set up your ScyllaDB monitoring, you need Scylla Operator already installed in your Kubernetes cluster. +For more information on how to deploy Scylla Operator, see:

      + +

      The above example of the monitoring setup also makes use of HAProxy Ingress and Prometheus Operator. +You can deploy them in your Kubernetes cluster using the provided third party examples. If you already have them deployed +in your cluster, you can skip the below steps.

      +
      +

      Deploy Prometheus Operator

      +

      Deploy Prometheus Operator using kubectl:

      +
      $ kubectl -n prometheus-operator apply --server-side -f ./examples/third-party/prometheus-operator
      +
      +
      +
      +
      Wait for Prometheus Operator to roll out
      +
      $ kubectl -n prometheus-operator rollout status --timeout=5m deployments.apps/prometheus-operator
      +deployment "prometheus-operator" successfully rolled out
      +
      +
      +
      +
      +
      +

      Deploy HAProxy Ingress

      +

      Deploy HAProxy Ingress using kubectl:

      +
      $ kubectl -n haproxy-ingress apply --server-side -f ./examples/third-party/haproxy-ingress
      +
      +
      +
      +
      Wait for HAProxy Ingress to roll out
      +
      $ kubectl -n haproxy-ingress rollout status --timeout=5m deployments.apps/haproxy-ingress
      +deployment "haproxy-ingress" successfully rolled out
      +
      +
      +
      +
      +
      +
      +

      Deploy ScyllaDBMonitoring

      +

      First, update the endpointsSelector in examples/monitoring/v1alpha1/scylladbmonitoring.yaml with a label +matching your ScyllaCluster instance name.

      +

      Deploy the monitoring setup using kubectl:

      +
      $ kubectl -n scylla apply --server-side -f ./examples/monitoring/v1alpha1/scylladbmonitoring.yaml
      +
      +
      +

      Scylla Operator will notice the new ScyllaDBMonitoring object, and it will reconcile all necessary resources.

      +
      +

      Wait for ScyllaDBMonitoring to roll out

      +
      $ kubectl wait --for='condition=Progressing=False' scylladbmonitorings.scylla.scylladb.com/example
      +scylladbmonitoring.scylla.scylladb.com/example condition met
      +
      +$ kubectl wait --for='condition=Degraded=False' scylladbmonitorings.scylla.scylladb.com/example
      +scylladbmonitoring.scylla.scylladb.com/example condition met
      +
      +$ kubectl wait --for='condition=Available=True' scylladbmonitorings.scylla.scylladb.com/example
      +scylladbmonitoring.scylla.scylladb.com/example condition met
      +
      +
      +
      +
      +

      Wait for Prometheus to roll out

      +
      $ kubectl rollout status --timeout=5m statefulset.apps/prometheus-example
      +statefulset rolling update complete 1 pods at revision prometheus-example-65b89d55bb...
      +
      +
      +
      +
      +

      Wait for Grafana to roll out

      +
      $ kubectl rollout status --timeout=5m deployments.apps/example-grafana
      +deployment "example-grafana" successfully rolled out
      +
      +
      +
      +
      +
      +

      Accessing Grafana

      +

      For accessing Grafana service from outside the Kubernetes cluster we recommend using an Ingress, although there are many other ways to do so. +When using Ingress, what matters is to direct your packets to the ingress controller Service/Pods and have the correct TLS SNI field set by the caller when reaching out to the service, so it is routed properly, and your client can successfully validate the grafana serving certificate. +This is easier when you are using a real DNS domain that resolves to your Ingress controller’s IP address but most clients and tools allow setting the SNI field manually.

      +
      +
      +

      Prerequisites

      +

      To access Grafana, you first need to collect the serving CA and the credentials.

      +
      $ GRAFANA_SERVING_CERT="$( kubectl -n scylla get secret/example-grafana-serving-ca --template '{{ index .data "tls.crt" }}' | base64 -d )"
      +$ GRAFANA_USER="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "username" }}' | base64 -d )"
      +$ GRAFANA_PASSWORD="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "password" }}' | base64 -d )"
      +
      +
      +
      +
      +

      Connecting through Ingress using a resolvable domain

      +

      In production clusters, the Ingress controller and appropriate DNS records should be set up already. Often there is already a generic wildcard record like *.app.mydomain pointing to the Ingress controller’s external IP. For custom service domains, it is usually a CNAME pointing to the Ingress controller’s A record.

      +

      Note: The ScyllaDBMonitoring example creates an Ingress object with test-grafana.test.svc.cluster.local DNS domain that you should adjust to your domain. Below examples use example-grafana.apps.mydomain.

      +

      Note: To test a resolvable domain from your machine without creating DNS records, you can adjust /etc/hosts or similar.

      +
      $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://example-grafana.apps.mydomain" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
      +200
      +
      +
      +
      +
      +

      Connecting through Ingress using an unresolvable domain

      +

      To connect to an Ingress without a resolvable domain you first need to find out your Ingress controller’s IP that can be resolved externally. Again, there are many ways to do so beyond the below examples.

      +

      Unless stated otherwise, we assume your Ingress is running on port 443.

      +
      $ INGRESS_PORT=443
      +
      +
      +
      +

      Variants

      +
      +
      Ingress ExternalIP
      +

      When you are running in a real cluster there is usually a cloud LoadBalancer or a bare metal alternative providing you with an externally reachable IP address.

      +
      $ INGRESS_IP="$( kubectl -n=haproxy-ingress get service/haproxy-ingress --template='{{ ( index .status.loadBalancer.ingress 0 ).ip }}' )"
      +
      +
      +
      +
      +
      Ingress NodePort
      +

      NodePort is slightly less convenient, but it’s available in development clusters as well.

      +
      $ INGRESS_IP="$( kubectl get nodes --template='{{ $internal_ip := "" }}{{ $external_ip := "" }}{{ range ( index .items 0 ).status.addresses }}{{ if eq .type "InternalIP" }}{{ $internal_ip = .address }}{{ else if eq .type "ExternalIP" }}{{ $external_ip = .address }}{{ end }}{{ end }}{{ if $external_ip }}{{ $external_ip }}{{ else }}{{ $internal_ip }}{{ end }}' )"
      +$ INGRESS_PORT="$( kubectl -n=haproxy-ingress get services/haproxy-ingress --template='{{ range .spec.ports }}{{ if eq .port 443 }}{{ .nodePort }}{{ end }}{{ end }}' )"
      +
      +
      +
      +
      +
      Connection
      +
      $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://test-grafana.test.svc.cluster.local:${INGRESS_PORT}" --resolve "test-grafana.test.svc.cluster.local:${INGRESS_PORT}:${INGRESS_IP}" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
      +200
      +
      +
      +
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/multidc/eks.html b/master/multidc/eks.html new file mode 100644 index 00000000000..2a66fadf6ff --- /dev/null +++ b/master/multidc/eks.html @@ -0,0 +1,791 @@ + + + + + + + + + + + + + Build multiple Amazon EKS clusters with inter-Kubernetes networking | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Build multiple Amazon EKS clusters with inter-Kubernetes networking

      +

      This document describes the process of creating multiple Amazon EKS clusters in different regions, using separate VPCs, and explains the steps necessary for configuring inter-Kubernetes networking between the clusters. +The interconnected clusters can serve as a platform for deploying a multi-datacenter ScyllaDB cluster.

      +

      This guide will walk you through the process of creating and configuring EKS clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference.

      +
      +

      Prerequisites

      +

      To follow the below guide, you first need to install and configure the tools that you will need to create and manage AWS and Kubernetes resources:

      +
        +
      • eksctl – A command line tool for working with EKS clusters.

      • +
      • kubectl – A command line tool for working with Kubernetes clusters.

      • +
      +

      For more information see Getting started with Amazon EKS – eksctl in AWS documentation.

      +
      +
      +

      Create EKS clusters

      +
      +

      Create the first EKS cluster

      +

      Below is the required specification for the first cluster.

      +
      apiVersion: eksctl.io/v1alpha5
      +kind: ClusterConfig
      +
      +metadata:
      +  name: scylladb-us-east-1
      +  region: us-east-1
      +
      +availabilityZones:
      +- us-east-1a
      +- us-east-1b
      +- us-east-1c
      +
      +vpc:
      +  cidr: 10.0.0.0/16
      +
      +nodeGroups:
      +  ...
      +
      +
      +

      Specify the first cluster’s configuration file and save it as cluster-us-east-1.yaml. +Refer to Creating an EKS cluster section of ScyllaDB Operator documentation for the reference of the configuration of node groups.

      +

      To deploy the first cluster, use the below command:

      +
      eksctl create cluster -f=cluster-us-east-1.yaml
      +
      +
      +

      Run the following command to learn the status and VPC ID of the cluster:

      +
      eksctl get cluster --name=scylladb-us-east-1 --region=us-east-1
      +
      +
      +

      You will need to get the cluster’s context for future operations. To do so, use the below command:

      +
      kubectl config current-context
      +
      +
      +

      For any kubectl commands that you will want to run against this cluster, use the --context flag with the value returned by the above command.

      +
      +

      Deploy ScyllaDB Operator

      +

      Once the cluster is ready, refer to Deploying Scylla on a Kubernetes Cluster to deploy the ScyllaDB Operator and its prerequisites.

      +
      +
      +

      Prepare nodes for running ScyllaDB

      +

      Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in Deploying Scylla on EKS in ScyllaDB Operator documentation.

      +
      +
      +
      +

      Create the second EKS cluster

      +

      Below is the required specification for the second cluster. As was the case with the first cluster, the provided values are only exemplary and can be adjusted according to your needs.

      +
      +

      Caution

      +

      It is required that the VPCs of the two EKS clusters have non-overlapping IPv4 network ranges.

      +
      +
      apiVersion: eksctl.io/v1alpha5
      +kind: ClusterConfig
      +
      +metadata:
      +  name: scylladb-us-east-2
      +  region: us-east-2
      +
      +availabilityZones:
      +- us-east-2a
      +- us-east-2b
      +- us-east-2c
      +
      +vpc:
      +  cidr: 172.16.0.0/16
      +
      +nodeGroups:
      +  ...
      +
      +
      +

      Follow analogous steps to create the second EKS cluster and prepare it for running ScyllaDB.

      +
      +
      +
      +

      Configure the network

      +

      The prepared Kubernetes clusters each have a dedicated VPC network. +To be able to route the traffic between the two VPC networks, you need to create a networking connection between them, otherwise known as VPC peering.

      +
      +

      Create VPC peering

      +

      Refer to Create a VPC peering connection in AWS documentation for instructions on creating a VPC peering connection between the two earlier created VPCs.

      +

      In this example, the ID of the created VPC peering connection is pcx-08077dcc008fbbab6.

      +
      +
      +

      Update route tables

      +

      To enable private IPv4 traffic between the instances in the VPC peered network, you need to establish a communication channel by adding a route to the route tables associated with all the subnets associated with the instances for both VPCs. +The destination of the new route in a given route table is the CIDR of the VPC of the other cluster and the target is the ID of the VPC peering connection.

      +

      The following is an example of the route tables that enable communication of instances in two peered VPCs. Each table has a local route and the added route which sends traffic targeted at the other VPC to the peered network connection. The other preconfigured routes are omitted for readability.

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Route tableDestinationTarget
      eksctl-scylladb-us-east-1-cluster/PublicRouteTable10.0.0.0/16local
      172.16.0.0/16pcx-08077dcc008fbbab6
      eksctl-scylladb-us-east-2-cluster/PublicRouteTable172.16.0.0/16local
      10.0.0.0/16pcx-08077dcc008fbbab6
      +

      Refer to Update your route tables for a VPC peering connection in AWS documentation for more information.

      +
      +
      +

      Update security groups

      +

      To allow traffic to flow to and from instances associated with security groups in the peered VPC, you need to update the inbound rules of the VPCs’ shared security groups.

      +

      Below is an example of the inbound rules that to be added to the corresponding security groups of the two VPCs.

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

      Security group name

      Type

      Protocol

      Port range

      Source

      eksctl-scylladb-us-east-1-cluster-ClusterSharedNodeSecurityGroup-TD05V9EVU3B8

      All traffic

      All

      All

      Custom 172.16.0.0/16

      eksctl-scylladb-us-east-2-cluster-ClusterSharedNodeSecurityGroup-1FR9YDLU0VE7M

      All traffic

      All

      All

      Custom 10.0.0.0/16

      +

      The names of the shared security groups of your VPCs should be similar to the ones presented in the example.

      +
      +

      Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters in ScyllaDB Operator documentation for guidance.

      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/multidc/gke.html b/master/multidc/gke.html new file mode 100644 index 00000000000..75e8cddc2a9 --- /dev/null +++ b/master/multidc/gke.html @@ -0,0 +1,761 @@ + + + + + + + + + + + + + Build multiple GKE clusters with inter-Kubernetes networking | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Build multiple GKE clusters with inter-Kubernetes networking

      +

      This document describes the process of creating multiple GKE clusters in a shared VPC and explains the steps necessary for configuring inter-Kubernetes networking between clusters in different regions. +The interconnected clusters can serve as a platform for deploying a Multi Datacenter ScyllaDB cluster.

      +

      This guide will walk you through the process of creating and configuring GKE clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference.

      +
      +

      Prerequisites

      +

      To follow the below guide, you first need to install and configure the following tools that you will need to create and manage GCP and Kubernetes resources:

      +
        +
      • gcloud CLI - Google Cloud Command Line Interface, a command line tool for working with Google Cloud resources and services directly.

      • +
      • kubectl – A command line tool for working with Kubernetes clusters.

      • +
      +

      See Install the Google Cloud CLI in GCP documentation and Install Tools in Kubernetes documentation for reference.

      +
      +
      +

      Create and configure a VPC network

      +

      For the clusters to have inter-Kubernetes networking, you will create a virtual network shared between all the instances, with dedicated subnets for each of the clusters. +To create the subnets manually, create the network in custom subnet mode.

      +
      +

      Create the VPC network

      +

      Run the below command to create the network:

      +
      gcloud compute networks create scylladb --subnet-mode=custom
      +
      +
      +

      With the VPC network created, create a dedicated subnet with secondary CIDR ranges for their Pod and Service pools in each region which the clusters will reside in.

      +
      +
      +

      Create VPC network subnets

      +

      To create a subnet for the first cluster in region us-east1, run the below command:

      +
      gcloud compute networks subnets create scylladb-us-east1 \
      +    --region=us-east1 \
      +    --network=scylladb \
      +    --range=10.0.0.0/20 \
      +    --secondary-range='cluster=10.1.0.0/16,services=10.2.0.0/20'
      +
      +
      +

      To create a subnet for the second cluster in region us-west1, run the below command:

      +
      gcloud compute networks subnets create scylladb-us-west1 \
      +    --region=us-west1 \
      +    --network=scylladb \
      +    --range=172.16.0.0/20 \
      +    --secondary-range='cluster=172.17.0.0/16,services=172.18.0.0/20'
      +
      +
      +
      +

      Caution

      +

      It is required that the IPv4 address ranges of the subnets allocated for the GKE clusters do not overlap.

      +
      +

      Refer to Create a VPC-native cluster and Alias IP ranges in GKE documentation for more information about VPC native clusters and alias IP ranges.

      +
      +
      +
      +

      Create GKE clusters

      +

      With the VPC network created, you will now create two VPC native GKE clusters in dedicated regions.

      +
      +

      Create the first GKE cluster

      +

      Run the following command to create the first GKE cluster in the us-east1 region:

      +
      gcloud container clusters create scylladb-us-east1 \
      +    --location=us-east1-b \
      +    --node-locations='us-east1-b,us-east1-c' \
      +    --machine-type=n1-standard-8 \
      +    --num-nodes=1 \
      +    --disk-type=pd-ssd \
      +    --disk-size=20 \
      +    --image-type=UBUNTU_CONTAINERD \
      +    --no-enable-autoupgrade \
      +    --no-enable-autorepair \
      +    --enable-ip-alias \
      +    --network=scylladb \
      +    --subnetwork=scylladb-us-east1 \
      +    --cluster-secondary-range-name=cluster \
      +    --services-secondary-range-name=services
      +
      +
      +

      Refer to Creating a GKE cluster section of ScyllaDB Operator documentation for more information regarding the configuration and deployment of additional node pools, including the one dedicated for ScyllaDB nodes.

      +

      You will need to get the cluster’s context for future operations. To do so, use the below command:

      +
      kubectl config current-context
      +
      +
      +

      For any kubectl commands that you will want to run against this cluster, use the --context flag with the value returned by the above command.

      +
      +

      Deploy ScyllaDB Operator

      +

      Once the cluster is ready, refer to Deploying Scylla on a Kubernetes Cluster to deploy the ScyllaDB Operator and its prerequisites.

      +
      +
      +

      Prepare nodes for running ScyllaDB

      +

      Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in Deploying Scylla on GKE page of the documentation.

      +
      +
      +
      +

      Create the second GKE cluster

      +

      Run the following command to create the second GKE cluster in the us-west1 region:

      +
      gcloud container clusters create scylladb-us-west1 \
      +    --location=us-west1-b \
      +    --node-locations='us-west1-b,us-west1-c' \
      +    --machine-type=n1-standard-8 \
      +    --num-nodes=1 \
      +    --disk-type=pd-ssd \
      +    --disk-size=20 \
      +    --image-type=UBUNTU_CONTAINERD \
      +    --no-enable-autoupgrade \
      +    --no-enable-autorepair \
      +    --enable-ip-alias \
      +    --network=scylladb \
      +    --subnetwork=scylladb-us-west1 \
      +    --cluster-secondary-range-name=cluster \
      +    --services-secondary-range-name=services
      +
      +
      +

      Follow analogous steps to create the second GKE cluster and prepare it for running ScyllaDB.

      +
      +
      +
      +

      Configure the firewall rules

      +

      When creating a cluster, GKE creates several ingress firewall rules that enable the instances to communicate with each other. +To establish interconnectivity between the two created Kubernetes clusters, you will now add the allocated IPv4 address ranges to their corresponding source address ranges.

      +

      First, retrieve the name of the firewall rule associated with the first cluster, which permits traffic between all Pods on a cluster, as required by the Kubernetes networking model. +The rule name is in the following format: gke-[cluster-name]-[cluster-hash]-all.

      +

      To retrieve it, run the below command:

      +
      gcloud compute firewall-rules list --filter='name~gke-scylladb-us-east1-.*-all'
      +
      +
      +

      The output should resemble the following:

      +
      NAME                                NETWORK   DIRECTION  PRIORITY  ALLOW                     DENY  DISABLED
      +gke-scylladb-us-east1-f17db261-all  scylladb  INGRESS    1000      udp,icmp,esp,ah,sctp,tcp        False
      +
      +
      +

      Modify the rule by updating the rule’s source ranges with the allocated Pod IPv4 address ranges of both clusters:

      +
      gcloud compute firewall-rules update gke-scylladb-us-east1-f17db261-all --source-ranges='10.1.0.0/16,172.17.0.0/16'
      +
      +
      +

      Follow the analogous steps for the other cluster. In this example, its corresponding firewall rule name is gke-scylladb-us-west1-0bb60902-all. To update it, you would run:

      +
      gcloud compute firewall-rules update gke-scylladb-us-west1-0bb60902-all --source-ranges='10.1.0.0/16,172.17.0.0/16'
      +
      +
      +

      Refer to Automatically created firewall rules in GKE documentation for more information.

      +
      +

      Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters in ScyllaDB Operator documentation for guidance.

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/multidc/index.html b/master/multidc/index.html new file mode 100644 index 00000000000..bbde5d24cab --- /dev/null +++ b/master/multidc/index.html @@ -0,0 +1,602 @@ + + + + + + + + + + + + + Deploying multi-datacenter ScyllaDB clusters in Kubernetes | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Deploying multi-datacenter ScyllaDB clusters in Kubernetes

      +

      Prepare a platform for a multi datacenter ScyllaDB cluster deployment:

      + +

      Deploy a multi-datacenter ScyllaDB cluster in Kubernetes:

      + +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/multidc/multidc.html b/master/multidc/multidc.html new file mode 100644 index 00000000000..f9b13e77806 --- /dev/null +++ b/master/multidc/multidc.html @@ -0,0 +1,1192 @@ + + + + + + + + + + + + + Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters

      +

      This document describes the process of deploying a Multi Datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters.

      +

      This guide will walk you through the example procedure of deploying two datacenters in distinct regions of a selected cloud provider.

      +
      +

      Note

      +

      This guide is dedicated to deploying multi-datacenter ScyllaDB clusters and does not discuss unrelated configuration options. +For details of ScyllaDB cluster deployments and their configuration, refer to Deploying Scylla on a Kubernetes Cluster in ScyllaDB Operator documentation.

      +
      +
      +

      Prerequisites

      +

      As this document describes the procedure of deploying a Multi Datacenter ScyllaDB cluster, you are expected to have the required infrastructure prepared. +Let’s assume two interconnected Kubernetes clusters, capable of communicating with each other over PodIPs, with each cluster meeting the following requirements:

      +
        +
      • a node pool dedicated to ScyllaDB nodes composed of at least 3 nodes running in different zones (with unique topology.kubernetes.io/zone label), configured to run ScyllaDB, each labeled with scylla.scylladb.com/node-type: scylla

      • +
      • running ScyllaDB Operator and its prerequisites

      • +
      • running a storage provisioner capable of provisioning XFS volumes of StorageClass scylladb-local-xfs in each of the nodes dedicated to ScyllaDB instances

      • +
      +

      You can refer to one of our guides describing the process of preparing such infrastructure:

      + +

      Additionally, to follow the below guide, you need to install and configure the following tools that you will need to manage Kubernetes resources:

      +
        +
      • kubectl – A command line tool for working with Kubernetes clusters.

      • +
      +

      See Install Tools in Kubernetes documentation for reference.

      +
      +
      +

      Multi Datacenter ScyllaDB Cluster

      +

      In v1.11, ScyllaDB Operator introduced support for manual multi-datacenter ScyllaDB cluster deployments.

      +
      +

      Warning

      +

      ScyllaDB Operator only supports manual configuration of multi-datacenter ScyllaDB clusters. +In other words, although ScyllaCluster API exposes the machinery necessary for setting up multi-datacenter ScylaDB clusters, the ScyllaDB Operator only automates operations for a single datacenter.

      +

      Operations related to multiple datacenters may require manual intervention of a human operator. +Most notably, destroying one of the Kubernetes clusters or ScyllaDB datacenters is going to leave DN nodes behind in other datacenters, and their removal has to be carried out manually.

      +
      +

      The main mechanism used to set up a manual multi-datacenter ScyllaDB cluster is a field in ScyllaCluster’s specification - externalSeeds.

      +
      +

      External seeds

      +

      The externalSeeds field in ScyllaCluster’s specification enables control over external seeds that are propagated to ScyllaDB binary as --seed-provider-parameters seeds=<external-seeds>. +In this context, external should be understood as “external to the datacenter being specified by the API”. +The provided seeds are used by the nodes as initial points of contact, which allows them to discover the cluster ring topology when joining it.

      +

      Refer to Scylla Seed Nodes in ScyllaDB documentation for more information regarding the function of seed nodes in ScyllaDB. +For more details regarding the function and implementation of external seeds, refer to the original enhancement proposal.

      +
      +
      +

      Networking

      +

      Since this guide assumes interconnectivity over PodIPs of the Kubernetes clusters, you are going to configure the ScyllaDB cluster’s nodes to communicate over PodIPs. +This is enabled by a subset of exposeOptions specified in ScyllaCluster API, introduced in v1.11.

      +

      For this particular setup, define the ScyllaClusers as follows:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +spec:
      +  exposeOptions:
      +    nodeService:
      +      type: Headless
      +    broadcastOptions:
      +      clients:
      +        type: PodIP
      +      nodes:
      +        type: PodIP
      +
      +
      +

      However, other configuration options allow for the manual deployment of multi-datacenter ScyllaDB clusters in different network setups. For details, refer to Exposing ScyllaClusters in ScyllaDB Operator documentation.

      +
      +

      Deploy a multi-datacenter ScyllaDB Cluster

      +
      +
      +

      Using context

      +

      Let’s specify contexts for kubectl commands used throughout the guide. +To retrieve the context of your current cluster, run:

      +
      kubectl config current-context
      +
      +
      +

      Save the contexts of the two clusters, which you are going to deploy the datacenters in, as CONTEXT_DC1 and CONTEXT_DC2 environment variables correspondingly.

      +
      +
      +

      Deploy the first datacenter

      +

      First, run the below command to create a dedicated ‘scylla’ namespace:

      +
      kubectl --context="${CONTEXT_DC1}" create ns scylla
      +
      +
      +

      For this guide, let’s assume that your cluster is running in us-east-1 region and the nodes dedicated to running ScyllaDB nodes are running in zones us-east-1a, us-east-1b and us-east-1c correspondingly. If that is not the case, adjust the manifest accordingly.

      +
      +

      Caution

      +

      The .spec.name field of the ScyllaCluster objects represents the ScyllaDB cluster name and has to be consistent across all datacenters of this ScyllaDB cluster. +The names of the datacenters, specified in .spec.datacenter.name, have to be unique across the entire multi-datacenter cluster.

      +

      For more information see Create a ScyllaDB Cluster - Multi Data Centers (DC) in ScyllaDB documentation.

      +
      +

      Save the ScyllaCluster manifest in dc1.yaml:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +metadata:
      +  name: scylla-cluster
      +  namespace: scylla
      +spec:
      +  agentVersion: 3.2.5
      +  version: 5.4.0
      +  cpuset: true
      +  sysctls:
      +  - "fs.aio-max-nr=2097152"
      +  automaticOrphanedNodeCleanup: true
      +  exposeOptions:
      +    broadcastOptions:
      +      clients:
      +        type: PodIP
      +      nodes:
      +        type: PodIP
      +    nodeService:
      +      type: Headless
      +  datacenter:
      +    name: us-east-1
      +    racks:
      +    - name: a
      +      members: 1
      +      storage:
      +        storageClassName: scylladb-local-xfs
      +        capacity: 1800G
      +      agentResources:
      +        requests:
      +          cpu: 100m
      +          memory: 250M
      +        limits:
      +          cpu: 100m
      +          memory: 250M
      +      resources:
      +        requests:
      +          cpu: 7
      +          memory: 56G
      +        limits:
      +          cpu: 7
      +          memory: 56G
      +      placement:
      +        podAntiAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +          - topologyKey: kubernetes.io/hostname
      +            labelSelector:
      +              matchLabels:
      +                app.kubernetes.io/name: scylla
      +                scylla/cluster: scylla-cluster
      +        nodeAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +            nodeSelectorTerms:
      +            - matchExpressions:
      +              - key: topology.kubernetes.io/zone
      +                operator: In
      +                values:
      +                - us-east-1a
      +              - key: scylla.scylladb.com/node-type
      +                operator: In
      +                values:
      +                - scylla
      +        tolerations:
      +        - key: role
      +          operator: Equal
      +          value: scylla-clusters
      +          effect: NoSchedule
      +    - name: b
      +      members: 1
      +      storage:
      +        storageClassName: scylladb-local-xfs
      +        capacity: 1800G
      +      agentResources:
      +        requests:
      +          cpu: 100m
      +          memory: 250M
      +        limits:
      +          cpu: 100m
      +          memory: 250M
      +      resources:
      +        requests:
      +          cpu: 7
      +          memory: 56G
      +        limits:
      +          cpu: 7
      +          memory: 56G
      +      placement:
      +        podAntiAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +          - topologyKey: kubernetes.io/hostname
      +            labelSelector:
      +              matchLabels:
      +                app.kubernetes.io/name: scylla
      +                scylla/cluster: scylla-cluster
      +        nodeAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +            nodeSelectorTerms:
      +            - matchExpressions:
      +              - key: topology.kubernetes.io/zone
      +                operator: In
      +                values:
      +                - us-east-1b
      +              - key: scylla.scylladb.com/node-type
      +                operator: In
      +                values:
      +                - scylla
      +        tolerations:
      +        - key: role
      +          operator: Equal
      +          value: scylla-clusters
      +          effect: NoSchedule
      +    - name: c
      +      members: 1
      +      storage:
      +        storageClassName: scylladb-local-xfs
      +        capacity: 1800G
      +      agentResources:
      +        requests:
      +          cpu: 100m
      +          memory: 250M
      +        limits:
      +          cpu: 100m
      +          memory: 250M
      +      resources:
      +        requests:
      +          cpu: 7
      +          memory: 56G
      +        limits:
      +          cpu: 7
      +          memory: 56G
      +      placement:
      +        podAntiAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +          - topologyKey: kubernetes.io/hostname
      +            labelSelector:
      +              matchLabels:
      +                app.kubernetes.io/name: scylla
      +                scylla/cluster: scylla-cluster
      +        nodeAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +            nodeSelectorTerms:
      +            - matchExpressions:
      +              - key: topology.kubernetes.io/zone
      +                operator: In
      +                values:
      +                - us-east-1c
      +              - key: scylla.scylladb.com/node-type
      +                operator: In
      +                values:
      +                - scylla
      +        tolerations:
      +        - key: role
      +          operator: Equal
      +          value: scylla-clusters
      +          effect: NoSchedule
      +
      +
      +

      Apply the manifest:

      +
      kubectl --context="${CONTEXT_DC1}" apply --server-side -f=dc1.yaml
      +
      +
      +

      Wait for the cluster to be fully rolled out:

      +
      kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
      +
      +
      +
      scyllacluster.scylla.scylladb.com/scylla-cluster condition met
      +
      +
      +
      kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
      +
      +
      +
      scyllacluster.scylla.scylladb.com/scylla-cluster condition met
      +
      +
      +
      kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster
      +
      +
      +
      scyllacluster.scylla.scylladb.com/scylla-cluster condition met
      +
      +
      +

      You can now verify that all the nodes of your cluster are in UN state:

      +
      kubectl --context="${CONTEXT_DC1}" -n=scylla exec -it pod/scylla-cluster-us-east-1-a-0 -c=scylla -- nodetool status
      +
      +
      +

      The expected output should look similar to the below:

      +
      Datacenter: us-east-1
      +=====================
      +Status=Up/Down
      +|/ State=Normal/Leaving/Joining/Moving
      +--  Address      Load       Tokens       Owns    Host ID                               Rack
      +UN  10.0.70.195  290 KB     256          ?       494277b9-121c-4af9-bd63-3d0a7b9305f7  c
      +UN  10.0.59.24   559 KB     256          ?       a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37  b
      +UN  10.0.19.237  107 KB     256          ?       64b6292a-327f-4128-852a-6004039f402e  a
      +
      +
      +
      +
      Retrieve PodIPs of ScyllaDB nodes for use as external seeds
      +
      +

      Warning

      +

      Due to the ephemeral nature of PodIPs, it is ill-advised to use them as seeds in production environments. +This is because there is a high likelihood that the Pods of your ScyllaDB clusters will change their IPs during the cluster’s lifecycle, and so the provided seeds will no longer point to the ScyllaDB nodes. +It is undesired, as the seeds provided on node’s startup may serve as fallback contact points when all of the node’s peers are unreachable. +In production environments, it is recommended that you use domain names or non-ephemeral IP addresses as external seeds. +PodIPs are being used in this example for the sheer simplicity of this setup.

      +
      +

      Use the below commands and their expected outputs as a reference for retrieving the PodIPs used by the cluster for inter-node communication.

      +
      kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-a-0 --template='{{ .status.podIP }}'
      +
      +
      +
      10.0.19.237
      +
      +
      +
      kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-b-0 --template='{{ .status.podIP }}'
      +
      +
      +
      10.0.59.24
      +
      +
      +
      kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-c-0 --template='{{ .status.podIP }}'
      +
      +
      +
      10.0.70.195
      +
      +
      +

      You are going to utilize the retrieved addresses as seeds for the other datacenter.

      +
      +
      +
      +

      Deploy the second datacenter

      +

      To deploy the second datacenter, you will follow similar steps.

      +

      First, create a dedicated ‘scylla’ namespace:

      +
      kubectl --context="${CONTEXT_DC2}" create ns scylla
      +
      +
      +

      Replace the values in .spec.externalSeeds of the below manifest with the Pod IP addresses that you retrieved earlier. +The provided values are going to serve as initial contact points for the joining nodes of the second datacenter.

      +

      For this guide, let’s assume that the second cluster is running in us-east-2 region and the nodes dedicated for running ScyllaDB nodes are running in zones us-east-2a, us-east-2b and us-east-2c correspondingly. If that is not the case, adjust the manifest accordingly. +Having configured it, save the manifest as dc2.yaml:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +metadata:
      +  name: scylla-cluster
      +  namespace: scylla
      +spec:
      +  agentVersion: 3.2.5
      +  version: 5.4.0
      +  cpuset: true
      +  sysctls:
      +  - "fs.aio-max-nr=2097152"
      +  automaticOrphanedNodeCleanup: true
      +  exposeOptions:
      +    broadcastOptions:
      +      clients:
      +        type: PodIP
      +      nodes:
      +        type: PodIP
      +    nodeService:
      +      type: Headless
      +  externalSeeds:
      +  - 10.0.19.237
      +  - 10.0.59.24
      +  - 10.0.70.195
      +  datacenter:
      +    name: us-east-2
      +    racks:
      +    - name: a
      +      members: 1
      +      storage:
      +        storageClassName: scylladb-local-xfs
      +        capacity: 1800G
      +      agentResources:
      +        requests:
      +          cpu: 100m
      +          memory: 250M
      +        limits:
      +          cpu: 100m
      +          memory: 250M
      +      resources:
      +        requests:
      +          cpu: 7
      +          memory: 56G
      +        limits:
      +          cpu: 7
      +          memory: 56G
      +      placement:
      +        podAntiAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +          - topologyKey: kubernetes.io/hostname
      +            labelSelector:
      +              matchLabels:
      +                app.kubernetes.io/name: scylla
      +                scylla/cluster: scylla-cluster
      +        nodeAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +            nodeSelectorTerms:
      +            - matchExpressions:
      +              - key: topology.kubernetes.io/zone
      +                operator: In
      +                values:
      +                - us-east-2a
      +              - key: scylla.scylladb.com/node-type
      +                operator: In
      +                values:
      +                - scylla
      +        tolerations:
      +        - key: role
      +          operator: Equal
      +          value: scylla-clusters
      +          effect: NoSchedule
      +    - name: b
      +      members: 1
      +      storage:
      +        storageClassName: scylladb-local-xfs
      +        capacity: 1800G
      +      agentResources:
      +        requests:
      +          cpu: 100m
      +          memory: 250M
      +        limits:
      +          cpu: 100m
      +          memory: 250M
      +      resources:
      +        requests:
      +          cpu: 7
      +          memory: 56G
      +        limits:
      +          cpu: 7
      +          memory: 56G
      +      placement:
      +        podAntiAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +          - topologyKey: kubernetes.io/hostname
      +            labelSelector:
      +              matchLabels:
      +                app.kubernetes.io/name: scylla
      +                scylla/cluster: scylla-cluster
      +        nodeAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +            nodeSelectorTerms:
      +            - matchExpressions:
      +              - key: topology.kubernetes.io/zone
      +                operator: In
      +                values:
      +                - us-east-2b
      +              - key: scylla.scylladb.com/node-type
      +                operator: In
      +                values:
      +                - scylla
      +        tolerations:
      +        - key: role
      +          operator: Equal
      +          value: scylla-clusters
      +          effect: NoSchedule
      +    - name: c
      +      members: 1
      +      storage:
      +        storageClassName: scylladb-local-xfs
      +        capacity: 1800G
      +      agentResources:
      +        requests:
      +          cpu: 100m
      +          memory: 250M
      +        limits:
      +          cpu: 100m
      +          memory: 250M
      +      resources:
      +        requests:
      +          cpu: 7
      +          memory: 56G
      +        limits:
      +          cpu: 7
      +          memory: 56G
      +      placement:
      +        podAntiAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +          - topologyKey: kubernetes.io/hostname
      +            labelSelector:
      +              matchLabels:
      +                app.kubernetes.io/name: scylla
      +                scylla/cluster: scylla-cluster
      +        nodeAffinity:
      +          requiredDuringSchedulingIgnoredDuringExecution:
      +            nodeSelectorTerms:
      +            - matchExpressions:
      +              - key: topology.kubernetes.io/zone
      +                operator: In
      +                values:
      +                - us-east-2c
      +              - key: scylla.scylladb.com/node-type
      +                operator: In
      +                values:
      +                - scylla
      +        tolerations:
      +        - key: role
      +          operator: Equal
      +          value: scylla-clusters
      +          effect: NoSchedule
      +
      +
      +

      To apply the manifest, run:

      +
      kubectl --context="${CONTEXT_DC2}" -n=scylla apply --server-side -f=dc2.yaml
      +
      +
      +

      Wait for the second datacenter to roll out:

      +
      kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
      +
      +
      +
      scyllacluster.scylla.scylladb.com/scylla-cluster condition met
      +
      +
      +
      kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
      +
      +
      +
      scyllacluster.scylla.scylladb.com/scylla-cluster condition met
      +
      +
      +
      kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster
      +
      +
      +
      scyllacluster.scylla.scylladb.com/scylla-cluster condition met
      +
      +
      +

      You can verify that the nodes have joined the existing cluster and that you are now running a multi-datacenter ScyllaDB cluster by running nodetool status with the below command:

      +
      kubectl --context="${CONTEXT_DC2}" -n=scylla exec -it pod/scylla-cluster-us-east-2-a-0 -c=scylla -- nodetool status
      +
      +
      +
      Datacenter: us-east-1
      +=====================
      +Status=Up/Down
      +|/ State=Normal/Leaving/Joining/Moving
      +--  Address        Load       Tokens       Owns    Host ID                               Rack
      +UN  10.0.70.195    705 KB     256          ?       494277b9-121c-4af9-bd63-3d0a7b9305f7  c
      +UN  10.0.59.24     764 KB     256          ?       a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37  b
      +UN  10.0.19.237    634 KB     256          ?       64b6292a-327f-4128-852a-6004039f402e  a
      +Datacenter: us-east-2
      +=====================
      +Status=Up/Down
      +|/ State=Normal/Leaving/Joining/Moving
      +--  Address        Load       Tokens       Owns    Host ID                               Rack
      +UN  172.16.39.209  336 KB     256          ?       7c30ea55-7a4f-4d93-86f7-c881772ebe62  b
      +UN  172.16.25.18   759 KB     256          ?       665dde7e-e420-4db3-8c54-ca71efd39b2e  a
      +UN  172.16.87.27   503 KB     256          ?       c19c89cb-e24c-4062-9df4-2aa90ab29a99  c
      +
      +
      +
      +
      +
      +
      +

      Scylla Manager

      +

      To integrate a multi-datacenter ScyllaDB cluster with Scylla Manager, you must deploy the Scylla Manager in only one datacenter.

      +

      In this example, let’s choose the Kubernetes cluster deployed in the first datacenter to host it. +To deploy Scylla Manager, follow the steps described in Deploying Scylla Manager on a Kubernetes Cluster +in ScyllaDB Operator documentation.

      +

      In order to define the Scylla Manager tasks, add them to the ScyllaCluster object deployed in the same Kubernetes cluster +in which your Scylla Manager is running.

      +

      Every datacenter (represented by ScyllaCluster CR) is, by default, provisioned with a new, random Scylla Manager Agent auth token. +To use Scylla Manager with multiple datacenter (represented by ScyllaClusters), you have to make sure they all use the same token.

      +

      Extract it from the first datacenter with the below command:

      +
      kubectl --context="${CONTEXT_DC1}" -n=scylla get secrets/scylla-cluster-auth-token --template='{{ index .data "auth-token.yaml" }}' | base64 -d
      +
      +
      +
      auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf
      +
      +
      +

      Save the output, replace the token with your own, and patch the secret in the second datacenter with the below command:

      +
      kubectl --context="${CONTEXT_DC2}" -n=scylla patch secret/scylla-cluster-auth-token--type='json' -p='[{"op": "add", "path": "/stringData", "value": {"auth-token.yaml": "auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf"}}]'
      +
      +
      +

      Execute a rolling restart of the nodes in DC2 to make sure they pick up the new token:

      +
      kubectl --context="${CONTEXT_DC2}" -n=scylla patch scyllacluster/scylla-cluster --type='merge' -p='{"spec": {"forceRedeploymentReason": "sync scylla-manager-agent token ('"$( date )"')"}}'
      +
      +
      +
      +
      +

      ScyllaDBMonitoring

      +

      To monitor your cluster, deploy ScyllaDBMonitoring in every datacenter independently. +To deploy ScyllaDB Monitoring, follow the steps described in Deploy managed monitoring in ScyllaDB Operator documentation.

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/nodeoperations/automatic-cleanup.html b/master/nodeoperations/automatic-cleanup.html new file mode 100644 index 00000000000..89a56771017 --- /dev/null +++ b/master/nodeoperations/automatic-cleanup.html @@ -0,0 +1,599 @@ + + + + + + + + + + + + + Automatic cleanup and replacement in case when k8s node is lost | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Automatic cleanup and replacement in case when k8s node is lost

      +

      In case when your k8s cluster loses one of the nodes due to incident or explicit removal, Scylla Pods may become unschedulable due to PVC node affinity.

      +

      When automaticOrphanedNodeCleanup flag is enabled in your ScyllaCluster, Scylla Operator will perform automatic +node replacement of a Pod which lost his bound resources.

      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/nodeoperations/index.html b/master/nodeoperations/index.html new file mode 100644 index 00000000000..c5f329333d9 --- /dev/null +++ b/master/nodeoperations/index.html @@ -0,0 +1,598 @@ + + + + + + + + + + + + + Node operations using Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Node operations using Scylla Operator

      + +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/nodeoperations/maintenance-mode.html b/master/nodeoperations/maintenance-mode.html new file mode 100644 index 00000000000..fef4711f26c --- /dev/null +++ b/master/nodeoperations/maintenance-mode.html @@ -0,0 +1,608 @@ + + + + + + + + + + + + + Maintenance mode | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + + + +
      +

      Maintenance mode

      +

      When maintenance mode is enabled, readiness probe of Scylla Pod will always return failure and liveness probe will always succeed. This causes that Pod under maintenance +is being removed from K8s Load Balancer and DNS registry but Pod itself stays alive.

      +

      This allows the Scylla Operator to interact with Scylla and Scylla dependencies inside the Pod. +For example user may turn off Scylla process, do something with the filesystem and bring the process back again.

      +

      To enable maintenance mode add scylla/node-maintenance label to service in front of Scylla Pod.

      +
      kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance=""
      +
      +
      +

      To disable, simply remove this label from service.

      +
      kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance-
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/nodeoperations/replace-node.html b/master/nodeoperations/replace-node.html new file mode 100644 index 00000000000..5c593891b24 --- /dev/null +++ b/master/nodeoperations/replace-node.html @@ -0,0 +1,682 @@ + + + + + + + + + + + + + Replacing a Scylla node | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + + + +
      +

      Replacing a Scylla node

      +
      +

      Replacing a dead node

      +

      In the case of a host failure, it may not be possible to bring back the node to life.

      +

      Replace dead node operation will cause the other nodes in the cluster to stream data to the node that was replaced. +This operation can take some time (depending on the data size and network bandwidth).

      +

      This procedure is for replacing one dead node. To replace more than one dead node, run the full procedure to completion one node at a time

      +

      Procedure

      +
        +
      1. Verify the status of the node using nodetool status command, the node with status DN is down and need to be replaced

        +
        kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
        +Datacenter: us-east-1
        +=====================
        +Status=Up/Down
        +|/ State=Normal/Leaving/Joining/Moving
        +--  Address        Load       Tokens       Owns    Host ID                               Rack
        +UN  10.43.125.110  74.63 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
        +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
        +DN  10.43.43.51    74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
        +
        +
        +
      2. +
      3. Identify service which is bound to down node by checking IP address

        +
        kubectl -n scylla get svc
        +NAME                                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                           AGE
        +simple-cluster-client                   ClusterIP   None            <none>        9180/TCP                                                          3h12m
        +simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.231.189   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h12m
        +simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.125.110   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h11m
        +simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.43.51     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h5m
        +
        +
        +
      4. +
      5. Drain node which we would like to replace using. This command may delete your data from local disks attached to given node!

        +
        kubectl drain gke-scylla-demo-default-pool-b4b390a1-6j12 --ignore-daemonsets --delete-local-data
        +
        +
        +

        Pod which will be replaced should enter the Pending state

        +
        kubectl -n scylla get pods
        +NAME                                    READY   STATUS    RESTARTS   AGE
        +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h21m
        +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h19m
        +simple-cluster-us-east-1-us-east-1a-2   0/2     Pending   0          8m14s
        +
        +
        +
      6. +
      7. To being node replacing, add scylla/replace="" label to service bound to pod we are replacing.

        +
        kubectl -n scylla label svc simple-cluster-us-east-1-us-east-1a-2 scylla/replace=""
        +
        +
        +

        Your failed Pod should be recreated on available k8s node

        +
        kubectl -n scylla get pods
        +NAME                                    READY   STATUS    RESTARTS   AGE
        +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h27m
        +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h25m
        +simple-cluster-us-east-1-us-east-1a-2   1/2     Running   0          9s
        +
        +
        +

        Because other nodes in cluster must stream data to new node this operation might take some time depending on how much data your cluster stores. +After bootstraping is over, your new Pod should be ready to go. +Old one shouldn’t be no longer visible in nodetool status

        +
        kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
        +Datacenter: us-east-1
        +=====================
        +Status=Up/Down
        +|/ State=Normal/Leaving/Joining/Moving
        +--  Address        Load       Tokens       Owns    Host ID                               Rack
        +UN  10.43.125.110  74.62 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
        +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
        +UN  10.43.191.172  74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
        +
        +
        +
      8. +
      9. Run the repair on the cluster to make sure that the data is synced with the other nodes in the cluster. +You can use Scylla Manager to run the repair.

      10. +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/nodeoperations/restore.html b/master/nodeoperations/restore.html new file mode 100644 index 00000000000..8f15121f72f --- /dev/null +++ b/master/nodeoperations/restore.html @@ -0,0 +1,799 @@ + + + + + + + + + + + + + Restore from backup | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + + + +
      +

      Restore from backup

      +

      This procedure will describe how to restore from backup taken using Scylla Manager to a fresh empty cluster of any size.

      +
      +

      Caution

      +

      Due to a bug in Scylla Manager not supporting ScyllaClusters having both non-TLS and TLS CQL ports open, you have to disable the TLS certificate management +in Scylla Operator. +This step will no longer be required, when the bug is fixed.

      +

      To disable TLS certificate management in Scylla Operator add --feature-gates="AutomaticTLSCertificates=false" flag to Scylla Operator deployment.

      +
      kubectl -n scylla-operator patch deployment/scylla-operator --type=json -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--feature-gates=AutomaticTLSCertificates=false"}]'
      +
      +
      +
      +

      In the following example, the ScyllaCluster, which was used to take the backup, is called source. Backup will be restored into the ScyllaCluster named target.

      +
      + +
      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +metadata:
      +  name: source
      +  namespace: scylla
      +spec:
      +  agentVersion: 3.2.5
      +  version: 5.4.1
      +  developerMode: true
      +  backups:
      +  - name: foo
      +    location:
      +    - s3:source-backup
      +    keyspace:
      +    - '*'
      +  datacenter:
      +    name: us-east-1
      +    racks:
      +    - name: us-east-1a
      +      members: 1
      +      storage:
      +        capacity: 1Gi
      +      resources:
      +        limits:
      +          cpu: 1
      +          memory: 1Gi
      +
      +
      +
      + +
      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +metadata:
      +  name: target
      +  namespace: scylla
      +spec:
      +  agentVersion: 3.2.5
      +  version: 5.4.1
      +  developerMode: true
      +  datacenter:
      +    name: us-east-1
      +    racks:
      +    - name: us-east-1a
      +      members: 1
      +      storage:
      +        capacity: 1Gi
      +      resources:
      +        limits:
      +          cpu: 1
      +          memory: 1Gi
      +
      +
      +
      +
      +

      Make sure your target cluster is already registered in Scylla Manager. To get a list of all registered clusters, execute the following command:

      +
      $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool cluster list
      ++--------------------------------------+---------------------------------------+---------+-----------------+
      +| ID                                   | Name                                  | Port    | CQL credentials |
      ++--------------------------------------+---------------------------------------+---------+-----------------+
      +| af1dd5cd-0406-4974-949f-dc9842980080 | scylla/target                        | default | set             |
      +| ebd82268-efb7-407e-a540-3619ae053778 | scylla/source                        | default | set             |
      ++--------------------------------------+---------------------------------------+---------+-----------------+
      +
      +
      +

      Identify the tag of a snapshot which you want to restore. To get a list of all available snapshots, execute following command:

      +
      kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c <CLUSTER_ID> --all-clusters -L <BACKUP_LOCATION>
      +
      +
      +

      Where:

      +
        +
      • CLUSTER_ID - the name or ID of a registered cluster with access to BACKUP_LOCATION.

      • +
      • BACKUP_LOCATION - the location in which the backup is stored.

      • +
      +

      In this example, BACKUP_LOCATION is s3:source-backup. Use the name of cluster which has access to the backup location for CLUSTER_ID. +In this example, it’s scylla/target.

      +
      $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c scylla/target --all-clusters -L s3:source-backup
      +backup/ff36d7e0-af2e-458c-afe6-868e0f3396b2
      +Snapshots:
      +  - sm_20240105115931UTC (409MiB, 1 nodes)
      +Keyspaces:
      +  - system_schema (15 tables)
      +  - users (9 tables)
      +
      +
      +

      In the below commands, we are restoring the sm_20240105115931UTC snapshot. Replace it with a tag of a snapshot that you want to restore. +Restoring consist of two steps. First, you’ll restore the schema, and then the data. +To restore schema, create a restore task manually on target ScyllaCluster by executing following command:

      +
      kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager --  sctool restore -c <CLUSTER_ID> -L <BACKUP_LOCATION> -T <SNAPSHOT_TAG> --restore-schema
      +
      +
      +

      Where:

      +
        +
      • CLUSTER_ID - a name or ID of a cluster you want to restore into.

      • +
      • BACKUP_LOCATION - the location in which the backup is stored.

      • +
      • SNAPSHOT_TAG - a tag of a snapshot that you want to restore.

      • +
      +

      When the task is created, the command will output the ID of a restore task.

      +
      $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-schema
      +restore/57228c52-7cf6-4271-8c8d-d446ff160747
      +
      +
      +

      Use the following command to check progress of the restore task:

      +
      $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/57228c52-7cf6-4271-8c8d-d446ff160747
      +Restore progress
      +Run:            0dd20cdf-abc4-11ee-951c-6e7993cf42ed
      +Status:         DONE - restart required (see restore docs)
      +Start time:     05 Jan 24 12:15:02 UTC
      +End time:       05 Jan 24 12:15:09 UTC
      +Duration:       6s
      +Progress:       100% | 100%
      +Snapshot Tag:   sm_20240105115931UTC
      +
      ++---------------+-------------+----------+----------+------------+--------+
      +| Keyspace      |    Progress |     Size |  Success | Downloaded | Failed |
      ++---------------+-------------+----------+----------+------------+--------+
      +| system_schema | 100% | 100% | 214.150k | 214.150k |   214.150k |      0 |
      ++---------------+-------------+----------+----------+------------+--------+
      +
      +
      +

      As suggested in the progress output, you will need to execute a rolling restart of the ScyllaCluster.

      +
      kubectl patch scyllacluster target --type merge -p '{"spec": {"forceRedeploymentReason": "schema restored"}}'
      +
      +
      +

      Use the following commands to wait until restart is finished:

      +
      $ kubectl wait --for='condition=Progressing=False' -n scylla scyllaclusters.scylla.scylladb.com/target
      +scyllacluster.scylla.scylladb.com/target condition met
      +
      +$ kubectl wait --for='condition=Degraded=False' -n scylla scyllaclusters.scylla.scylladb.com/target
      +scyllacluster.scylla.scylladb.com/target condition met
      +
      +$ kubectl wait --for='condition=Available=True' -n scylla scyllaclusters.scylla.scylladb.com/target
      +scyllacluster.scylla.scylladb.com/target condition met
      +
      +
      +

      To restore the tables content, create a restore task manually on target ScyllaCluster by executing the following command:

      +
      kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c <CLUSTER_ID> -L <BACKUP_LOCATION> -T <SNAPSHOT_TAG> --restore-tables
      +
      +
      +

      Where:

      +
        +
      • CLUSTER_ID - a name or ID of a cluster you want to restore into.

      • +
      • BACKUP_LOCATION - the location in which the backup is stored.

      • +
      • SNAPSHOT_TAG - a tag of a snapshot that you want to restore.

      • +
      +

      When the task is created, the command will output the ID of a restore task.

      +
      $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-tables
      +restore/63642069-bed5-4def-ba0f-68c49e47ace1
      +
      +
      +

      Use the following command to check progress of the restore task:

      +
      $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/63642069-bed5-4def-ba0f-68c49e47ace1
      +Restore progress
      +Run:            ab015cef-abc8-11ee-9521-6e7993cf42ed
      +Status:         DONE
      +Start time:     05 Jan 24 12:48:04 UTC
      +End time:       05 Jan 24 12:48:15 UTC
      +Duration:       11s
      +Progress:       100% | 100%
      +Snapshot Tag:   sm_20240105115931UTC
      +
      ++-------------+-------------+--------+---------+------------+--------+
      +| Keyspace    |    Progress |   Size | Success | Downloaded | Failed |
      ++-------------+-------------+--------+---------+------------+--------+
      +| users       | 100% | 100% | 409MiB |  409MiB |     409MiB |      0 |
      ++-------------+-------------+--------+---------+------------+--------+
      +
      +Post-restore repair progress
      +Run:            ab015cef-abc8-11ee-9521-6e7993cf42ed
      +Status:         DONE
      +Start time:     05 Jan 24 12:48:04 UTC
      +End time:       05 Jan 24 12:48:15 UTC
      +Duration:       11s
      +Progress:       100%
      +Intensity:      1
      +Parallel:       0
      +Datacenters:
      +  - us-east-1
      +
      ++-------------+--------------+----------+----------+
      +| Keyspace    |        Table | Progress | Duration |
      ++-------------+--------------+----------+----------+
      +| users       | users        | 100%     | 0s       |
      ++-------------+--------------+----------+----------+
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/nodeoperations/scylla-upgrade.html b/master/nodeoperations/scylla-upgrade.html new file mode 100644 index 00000000000..b752e276ca5 --- /dev/null +++ b/master/nodeoperations/scylla-upgrade.html @@ -0,0 +1,681 @@ + + + + + + + + + + + + + Upgrading version of Scylla | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Upgrading version of Scylla

      +

      To upgrade Scylla version using Operator user have to modify existing ScyllaCluster definition.

      +

      In this example cluster will be upgraded to version 4.4.5.

      +
      kubectl -n scylla patch ScyllaCluster simple-cluster  -p '{"spec":{"version": "4.4.5"}}' --type=merge
      +
      +
      +

      Operator supports two types of version upgrades:

      +
        +
      1. Patch upgrade

      2. +
      3. Generic upgrade

      4. +
      +

      Patch upgrade

      +

      Patch upgrade is executed when only patch version change is detected according to semantic versioning format. +Procedure simply rolls out a restart of whole cluster and upgrades Scylla container image for each node one by one.

      +

      Example: 4.0.0 -> 4.0.1

      +

      Generic upgrade

      +

      Generic upgrades are executed for the non patch version changes.

      +

      Example: 4.0.0 -> 2020.1.0 or 4.0.0 -> 4.1.0 or even 4.0.0 -> nightly

      +

      User can observe current state of upgrade in ScyllaCluster status.

      +
      kubectl -n scylla describe ScyllaCluster simple-cluster
      +[...]
      +Status:
      +  Racks:
      +    us-east-1a:
      +      Members:        3
      +      Ready Members:  3
      +      Version:        4.1.9
      +  Upgrade:
      +    Current Node:         simple-cluster-us-east-1-us-east-1a-2
      +    Current Rack:         us-east-1a
      +    Data Snapshot Tag:    so_data_20201228135002UTC
      +    From Version:         4.1.9
      +    State:                validate_upgrade
      +    System Snapshot Tag:  so_system_20201228135002UTC
      +    To Version:           4.2.2
      +
      +
      +

      Each upgrade begins with taking a snapshot of system and system_schema keyspaces on all nodes in parallel. +Name of this snapshot tag is saved in upgrade status under System Snapshot Tag.

      +

      Before nodes in rack are upgraded, underlying StatefulSet is changed to use OnDelete UpgradeStrategy. +This allows Operator have a full control over when Pod image is changed.

      +

      When a node is being upgraded, maintenance mode is enabled, then the node is drained and snapshot of all data keyspaces is taken. +Snapshot tag is saved under Data Snapshot Tag and is the same for all nodes during the procedure. +Once everything is set up, maintenance mode is disabled and Scylla Pod is deleted. Underlying StatefulSet will bring up a new +Pod with upgraded version. +Once Pod will become ready, data snapshot from this particular node is removed, and Operator moves to next node.

      +

      Once every rack is upgraded, system snapshot is removed from all nodes in parallel and previous StatefulSet UpgradeStrategy is restored. +At this point, all your nodes should be already in desired version.

      +

      Current state of upgrade can be traced using Current Node, Current Rack and State status fields.

      +
        +
      • Current Node shows which node is being upgraded.

      • +
      • Current Rack displays which rack is being upgraded.

      • +
      • State contain information at which stage upgrade is.

      • +
      +

      State can have following values:

      +
        +
      • begin_upgrade - upgrade is starting

      • +
      • check_schema_agreement - Operator waits until all nodes reach schema agreement. It waits for it for 1 minute, prints an error log message and check is retried.

      • +
      • create_system_backup - system keyspaces snapshot is being taken

      • +
      • find_next_rack - Operator finds out which rack must be upgraded next, decision is saved in Current Rack

      • +
      • upgrade_image_in_pod_spec - Image and UpgradeStrategy is upgraded in underlying StatefulSet

      • +
      • find_next_node - Operator finds out which node must be upgraded next, decision is saved in Current Node

      • +
      • enable_maintenance_mode - maintenance mode is being enabled

      • +
      • drain_node - node is being drained

      • +
      • backup_data - snapshot of data keyspaces is being taken

      • +
      • disable_maintenance_mode - maintenance mode is being disabled

      • +
      • delete_pod - Scylla Pod is being deleted

      • +
      • validate_upgrade - Operator validates if new pod enters Ready state and if Scylla version is upgraded

      • +
      • clear_data_backup - snapshot of data keyspaces is being removed

      • +
      • clear_system_backup - snapshot of system keyspaces is being removed

      • +
      • restore_upgrade_strategy - restore UpgradeStrategy in underlying StatefulSet

      • +
      • finish_upgrade - upgrade cleanup

      • +
      +

      Recovering from upgrade failure

      +

      Upgrade may get stuck on validate_upgrade stage. This happens when Scylla Pod refuses to properly boot up.

      +

      To continue with upgrade, first turn off operator by scaling Operator replicas to zero:

      +
      kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=0
      +
      +
      +

      Then user have to manually resolve issue with Scylla by checking what is the root cause of a failure in Scylla container logs. +If needed data and system keyspaces SSTable snapshots are available on the node. You can check ScyllaCluster status for their names.

      +

      Once issue is resolved and Scylla Pod is up and running (Pod is in Ready state), scale Operator back to two replicas:

      +
      kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=2
      +
      +
      +

      Operator should continue upgrade process from where it left off.

      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/objects.inv b/master/objects.inv new file mode 100644 index 00000000000..9eff5d92a8a Binary files /dev/null and b/master/objects.inv differ diff --git a/master/performance.html b/master/performance.html new file mode 100644 index 00000000000..26c788592e8 --- /dev/null +++ b/master/performance.html @@ -0,0 +1,685 @@ + + + + + + + + + + + + + Performance tuning | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Performance tuning

      +

      Scylla Operator 1.6 introduces a new experimental feature allowing users to optimize Kubernetes nodes.

      +
      +

      Node tuning

      +

      Starting from Operator 1.6, a new CRD called NodeConfig is available, allowing users to target Nodes which should be tuned. +When a Node is supposed to be optimized, the Scylla Operator creates a DaemonSet covering these Nodes. +Nodes matching the provided placement conditions will be subject to tuning.

      +

      Below example NodeConfig tunes nodes having scylla.scylladb.com/node-type=scylla label:

      +
      apiVersion: scylla.scylladb.com/v1alpha1
      +kind: NodeConfig
      +metadata:
      + name: cluster
      +spec:
      + placement:
      +   nodeSelector:
      +     scylla.scylladb.com/node-type: scylla
      +
      +
      +

      For more details about new CRD use:

      +
      kubectl explain nodeconfigs.scylla.scylladb.com/v1alpha1
      +
      +
      +

      For all optimizations we use a Python script available in the Scylla image called perftune. +Perftune executes the performance optmizations like tuning the kernel, network, disk devices, spreading IRQs across CPUs and more.

      +

      Tuning consists of two separate optimizations: common node tuning, and tuning based on Scylla Pods and their resource assignment. +Node tuning is executed immediately. Pod tuning is executed when Scylla Pod lands on the same Node.

      +

      Scylla works most efficently when it’s pinned to CPU and not interrupted. +One of the most common causes of context-switching are network interrupts. Packets coming to a node need to be processed, +and this requires CPU shares.

      +

      On K8s we always have at least a couple of processes running on the node: kubelet, kubernetes provider applications, daemons etc. +These processes require CPU shares, so we cannot dedicate entire node processing power to Scylla, we need to leave space for others.
      +We take advantage of it, and we pin IRQs to CPUs not used by any Scylla Pods exclusively.

      +

      Tuning resources are created in a special namespace called scylla-operator-node-tuning.

      +

      The tuning is applied only to pods with Guaranteed QoS class. Please double check your ScyllaCluster resource specification +to see if it meets all conditions.

      +
      +
      +

      Kubernetes tuning

      +

      By default, the kubelet uses the CFS quota to enforce pod CPU limits.
      +When the node runs many CPU-bound pods, the workload can move around different CPU cores depending on whether the pod +is throttled and which CPU cores are available. +However, kubelet may be configured to assign CPUs exclusively, by setting the CPU manager policy to static.

      +

      Setting up kubelet configuration is provider specific. Please check the docs for your distribution or talk to your +provider.

      +

      Only pods within the Guaranteed QoS class) can take advantage of this option. +When such pod lands on a Node, kubelet will pin them to specific CPUs, and those won’t be part of the shared pool.

      +

      In our case there are two requirements each ScyllaCluster must fulfill to receive a Guaranteed QoS class:

      +
        +
      • resource request and limits must be equal or only limits have to be provided

      • +
      • agentResources must be provided and their requests and limits must be equal, or only limits have to be provided

      • +
      +

      An example of such a ScyllaCluster that receives a Guaranteed QoS class is below:

      +
      apiVersion: scylla.scylladb.com/v1
      +kind: ScyllaCluster
      +metadata:
      +  name: guaranteed-cluster
      +  namespace: scylla
      +spec:
      +  agentVersion: 3.2.5
      +  version: 5.4.0
      +  datacenter:
      +    name: us-east-1
      +    racks:
      +    - name: us-east-1a
      +      members: 3
      +      storage:
      +        capacity: 500Gi
      +      agentResources:
      +        requests:
      +          cpu: 1
      +          memory: 1G
      +        limits:
      +          cpu: 1
      +          memory: 1G
      +      resources:
      +        requests:
      +          cpu: 4
      +          memory: 16G
      +        limits:
      +          cpu: 4
      +          memory: 16G
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/releases.html b/master/releases.html new file mode 100644 index 00000000000..1f3f4aa901c --- /dev/null +++ b/master/releases.html @@ -0,0 +1,849 @@ + + + + + + + + + + + + + Releases | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Releases

      +
      +

      Schedule

      +

      We are aiming to ship a new release approximately every 6 weeks. The following release schedule is only advisory, there are no commitments made to hitting these dates.

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

      Release

      Code freeze

      General availability

      1.12

      2023-12-18

      2024-01-08

      +
      +
      +

      Supported releases

      +

      We support the latest 2 releases of the operator to give everyone time to upgrade.

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

      Release

      General availability

      Support ends

      1.11

      2023-11-09

      Release of 1.13

      1.10

      2023-08-25

      Release of 1.12

      1.9

      2023-07-04

      2023-11-09

      1.8

      2023-01-25

      2023-08-25

      1.7

      2022-01-27

      2023-07-04

      1.6

      2021-12-03

      2023-01-25

      1.5

      2021-09-16

      2022-01-27

      1.4

      2021-08-10

      2021-12-03

      1.3

      2021-06-17

      2021-09-16

      1.2

      2021-05-06

      2021-08-10

      1.1

      2021-03-22

      2021-06-17

      1.0

      2021-01-21

      2021-05-06

      +
      +

      Backport policy

      +

      Usually, only important bug fixes are eligible for being backported. +This may depend on the situation and assessment of the maintainers.

      +
      +
      +
      +

      CI/CD

      +

      We use GitHub actions for our CI/CD. Every merge to a supported branch, or a creation of a tag will automatically trigger a job to build, test and publish the container image and other artifacts like helm charts. Before we publish any image, it must pass the e2e suite.

      +
      +

      Automated promotions

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

      Git reference

      Type

      Container image

      master

      branch

      docker.io/scylladb/scylla-operator:latest

      vX.Y

      branch

      docker.io/scylladb/scylla-operator:X.Y

      vX.Y.Z

      tag

      docker.io/scylladb/scylla-operator:X.Y.Z

      vX.Y.Z-alpha.N

      tag

      docker.io/scylladb/scylla-operator:X.Y.Z-alpha.N

      vX.Y.Z-beta.N

      tag

      docker.io/scylladb/scylla-operator:X.Y.Z-beta.N

      vX.Y.Z-rc.N

      tag

      docker.io/scylladb/scylla-operator:X.Y.Z-rc.N

      +
      +
      +

      Generally available

      +

      GA images aren’t build from scratch but rather promoted from an existing release candidates. When we decide a release candidate has the acceptable quality and QA sings it off, the release candidate is promoted to become the GA release. This makes sure the image has exactly the same content and SHA as the tested release candidate.

      +
      +
      +
      +

      Support matrix

      +

      Support matrix table shows the version requirements for a particular scylla-operator version. Be sure to match these requirements, otherwise some functionality will not work.

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

      v1.11

      v1.10

      v1.9

      v1.8

      v1.7

      v1.6

      v1.5

      v1.4

      v1.3

      v1.2

      v1.1

      v1.0

      Kubernetes

      >=1.21

      >=1.21

      >=1.21

      >=1.21

      >=1.20 && <1.25

      >=1.19.10 && <1.25

      >=1.19.10

      >=1.19.10

      >=1.19

      >=1.19

      >=1.11

      >=1.11

      CRI API

      v1

      v1

      v1

      v1alpha2

      v1alpha2

      v1alpha2

      Scylla OS

      >=5.0

      >=5.0

      >=5.0

      >=5.0

      >=4.3

      >=4.3

      >=4.3

      >=4.3

      >=4.2

      >=4.2

      >=4.0

      >=4.0

      Scylla Enterprise

      >=2021.1

      >=2021.1

      >=2021.1

      >=2021.1

      >=2021.1

      >=2021.1

      >=2021.1

      >=2021.1

      >=2020.1

      >=2020.1

      >=2020.1

      >=2020.1

      Scylla Manager

      >=2.6

      >=2.6

      >=2.6

      >=2.6

      >=2.2

      >=2.2

      >=2.2

      >=2.2

      >=2.2

      >=2.2

      >=2.2

      >=2.2

      Scylla Monitoring

      4.4.5

      >=4.0

      >=4.0

      >=4.0

      >=3.0

      >=3.0

      >=1.0

      >=1.0

      >=1.0

      >=1.0

      >=1.0

      >=1.0

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/search.html b/master/search.html new file mode 100644 index 00000000000..de11dc05ee8 --- /dev/null +++ b/master/search.html @@ -0,0 +1,574 @@ + + + + + + + + + + + + + Search | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + + + +
      + + + + + +
      + + +
      + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/searchindex.js b/master/searchindex.js new file mode 100644 index 00000000000..10d4c808c04 --- /dev/null +++ b/master/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["api-reference/groups/scylla.scylladb.com", "api-reference/groups/scylla.scylladb.com/nodeconfigs", "api-reference/groups/scylla.scylladb.com/scyllaclusters", "api-reference/groups/scylla.scylladb.com/scylladbmonitorings", "api-reference/groups/scylla.scylladb.com/scyllaoperatorconfigs", "api-reference/index", "contributing", "eks", "exposing", "generic", "gke", "helm", "index", "manager", "migration", "monitoring", "multidc/eks", "multidc/gke", "multidc/index", "multidc/multidc", "nodeoperations/automatic-cleanup", "nodeoperations/index", "nodeoperations/maintenance-mode", "nodeoperations/replace-node", "nodeoperations/restore", "nodeoperations/scylla-upgrade", "performance", "releases", "support/index", "support/known-issues", "support/must-gather", "support/overview", "support/troubleshooting/index", "support/troubleshooting/installation", "upgrade"], "filenames": ["api-reference/groups/scylla.scylladb.com.rst", "api-reference/groups/scylla.scylladb.com/nodeconfigs.rst", "api-reference/groups/scylla.scylladb.com/scyllaclusters.rst", "api-reference/groups/scylla.scylladb.com/scylladbmonitorings.rst", "api-reference/groups/scylla.scylladb.com/scyllaoperatorconfigs.rst", "api-reference/index.rst", "contributing.md", "eks.md", "exposing.md", "generic.md", "gke.md", "helm.md", "index.rst", "manager.md", "migration.md", "monitoring.md", "multidc/eks.md", "multidc/gke.md", "multidc/index.rst", "multidc/multidc.md", "nodeoperations/automatic-cleanup.md", "nodeoperations/index.rst", "nodeoperations/maintenance-mode.md", "nodeoperations/replace-node.md", "nodeoperations/restore.md", "nodeoperations/scylla-upgrade.md", "performance.md", "releases.md", "support/index.rst", "support/known-issues.md", "support/must-gather.md", "support/overview.md", "support/troubleshooting/index.rst", "support/troubleshooting/installation.md", "upgrade.md"], "titles": ["scylla.scylladb.com", "NodeConfig (scylla.scylladb.com/v1alpha1)", "ScyllaCluster (scylla.scylladb.com/v1)", "ScyllaDBMonitoring (scylla.scylladb.com/v1alpha1)", "ScyllaOperatorConfig (scylla.scylladb.com/v1alpha1)", "API Reference", "Contributing to Scylla Operator", "Deploying Scylla on EKS", "Exposing ScyllaCluster", "Deploying Scylla on a Kubernetes Cluster", "Deploying Scylla on GKE", "Deploying Scylla stack using Helm Charts", "Scylla Operator Documentation", "Deploying Scylla Manager on a Kubernetes Cluster", "Version migrations", "Monitoring", "Build multiple Amazon EKS clusters with inter-Kubernetes networking", "Build multiple GKE clusters with inter-Kubernetes networking", "Deploying multi-datacenter ScyllaDB clusters in Kubernetes", "Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters", "Automatic cleanup and replacement in case when k8s node is lost", "Node operations using Scylla Operator", "Maintenance mode", "Replacing a Scylla node", "Restore from backup", "Upgrading version of Scylla", "Performance tuning", "Releases", "Support", "Known issues", "Gathering data with must-gather", "Support overview", "Troubleshooting", "Troubleshooting installation issues", "Upgrade of Scylla Operator"], "terms": {"nodeconfig": [0, 5, 7, 10, 26], "v1alpha1": [0, 5, 14, 15, 26, 34], "scyllaclust": [0, 5, 11, 12, 13, 14, 15, 19, 20, 24, 25, 26, 30, 34], "v1": [0, 5, 8, 11, 13, 15, 19, 24, 26, 27], "scylladbmonitor": [0, 5], "scyllaoperatorconfig": [0, 5], "apivers": [1, 2, 3, 4, 8, 14, 15, 16, 19, 24, 26, 34], "kind": [1, 2, 3, 4, 8, 14, 15, 16, 19, 24, 26, 34], "pluralnam": [1, 2, 3, 4], "singularnam": [1, 2, 3, 4], "scope": [1, 2, 3, 4], "cluster": [1, 2, 3, 4, 11, 12, 14, 15, 20, 22, 23, 24, 25, 26, 34], "listkind": [1, 2, 3, 4], "nodeconfiglist": 1, "serv": [1, 2, 3, 4, 8, 9, 11, 15, 16, 17, 19, 33], "true": [1, 2, 3, 4, 7, 9, 11, 13, 15, 19, 24, 34], "storag": [1, 4, 7, 9, 10, 11, 15, 19, 24, 26, 34], "properti": [1, 2, 3, 4, 6, 8, 9], "string": [1, 2, 3, 4], "defin": [1, 2, 3, 4, 5, 8, 9, 11, 13, 19], "version": [1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 15, 19, 21, 24, 26, 27, 34], "schema": [1, 2, 3, 4, 24, 25], "thi": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 22, 23, 24, 25, 26, 27, 29, 30, 33, 34], "represent": [1, 2, 3, 4], "an": [1, 2, 3, 4, 6, 8, 9, 11, 12, 16, 17, 25, 26, 27, 30, 31, 33, 34], "object": [1, 2, 3, 4, 8, 9, 15, 19, 34], "server": [1, 2, 3, 4, 7, 9, 10, 13, 15, 19, 34], "should": [1, 2, 3, 4, 6, 8, 9, 11, 13, 14, 15, 16, 17, 19, 23, 25, 26], "convert": [1, 2, 3, 4], "recogn": [1, 2, 3, 4], "latest": [1, 2, 3, 4, 6, 7, 12, 27, 30], "intern": [1, 2, 3, 4, 8, 11, 13], "valu": [1, 2, 3, 4, 8, 9, 10, 11, 14, 16, 17, 19, 24, 25], "mai": [1, 2, 3, 4, 8, 15, 19, 20, 22, 23, 25, 26, 27, 30, 34], "reject": [1, 2, 3, 4], "unrecogn": [1, 2, 3, 4], "more": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 15, 16, 17, 19, 23, 26, 30, 31, 33], "info": [1, 2, 3, 4, 13, 30], "http": [1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15, 30, 34], "git": [1, 2, 3, 4, 6, 9, 14, 27, 34], "k8": [1, 2, 3, 4, 11, 12, 13, 14, 21, 22, 23, 26], "io": [1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 19, 27, 30, 34], "commun": [1, 2, 3, 4, 8, 16, 17, 19], "contributor": [1, 2, 3, 4, 6], "devel": [1, 2, 3, 4], "sig": [1, 2, 3, 4], "architectur": [1, 2, 3, 4], "api": [1, 2, 3, 4, 6, 9, 12, 13, 15, 19, 27, 30, 33], "convent": [1, 2, 3, 4, 9], "md": [1, 2, 3, 4], "resourc": [1, 4, 9, 13, 14, 15, 16, 17, 19, 20, 24, 26, 33, 34], "i": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 22, 23, 24, 25, 26, 27, 29, 30, 33, 34], "repres": [1, 2, 3, 4, 9, 19], "rest": [1, 2, 3, 4, 5, 9, 13, 30], "infer": [1, 2, 3, 4], "from": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 14, 15, 16, 19, 21, 22, 23, 25, 26, 27, 30, 34], "endpoint": [1, 2, 3, 4, 9], "client": [1, 3, 4, 6, 9, 11, 14, 15, 19, 23], "submit": [1, 2, 3, 4], "request": [1, 4, 11, 14, 15, 19, 26, 30, 31], "cannot": [1, 2, 3, 4, 13, 26], "updat": [1, 2, 3, 4, 9, 11, 13, 15, 17, 34], "In": [1, 2, 3, 4, 6, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 23, 24, 25, 26, 30, 34], "camelcas": [1, 2, 3, 4], "disableoptim": 1, "boolean": [1, 2, 3], "control": [1, 2, 3, 8, 10, 13, 14, 15, 19, 25, 33, 34], "node": [1, 3, 9, 11, 12, 13, 14, 15, 22, 24, 25], "match": [1, 2, 3, 10, 15, 26, 27], "requir": [1, 2, 3, 6, 7, 8, 9, 10, 16, 17, 19, 24, 26, 27, 29, 31, 33, 34], "ar": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 23, 24, 25, 26, 27, 30, 31, 33, 34], "go": [1, 2, 6, 9, 11, 14, 19, 23, 34], "optim": [1, 2, 7, 10, 26], "turn": [1, 22, 25, 34], "off": [1, 6, 9, 22, 25, 27, 34], "alreadi": [1, 2, 13, 15, 24, 25], "doe": [1, 2, 3, 6, 9, 11, 13, 19], "revert": 1, "chang": [1, 2, 3, 6, 9, 10, 11, 13, 14, 15, 19, 25, 34], "contain": [1, 2, 3, 8, 10, 11, 14, 17, 24, 25, 27, 30, 31, 34], "option": [1, 3, 7, 9, 10, 11, 13, 19, 26, 30], "automat": [1, 2, 3, 6, 9, 10, 13, 17, 21, 27, 34], "local": [1, 2, 3, 6, 15, 16, 19, 23], "disk": [1, 2, 7, 9, 10, 17, 23, 26], "setup": [1, 2, 3, 8, 9, 15, 16, 17, 19, 33], "schedul": [1, 2, 3], "rule": [1, 2, 3, 14, 16, 33], "pod": [1, 2, 3, 7, 8, 9, 10, 11, 13, 14, 15, 17, 19, 20, 22, 23, 25, 26, 30, 33], "arrai": [1, 2, 3, 7, 10], "list": [1, 2, 3, 6, 9, 10, 13, 14, 17, 24, 34], "configur": [1, 2, 3, 4, 8, 13, 19, 26, 33, 34], "filesystemconfigur": 1, "specifi": [1, 2, 3, 8, 9, 11, 16, 19], "path": [1, 2, 3, 6, 9, 14, 19, 24, 30, 34], "where": [1, 2, 3, 6, 7, 10, 14, 24, 25, 33], "desir": [1, 2, 3, 4, 9, 11, 13, 25], "creat": [1, 2, 3, 8, 11, 13, 14, 15, 19, 24, 26, 30, 34], "mountconfigur": 1, "fstype": [1, 2], "mountpoint": 1, "unsupportedopt": 1, "us": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 16, 17, 23, 24, 25, 26, 27, 30, 33, 34], "dure": [1, 2, 3, 6, 19, 25, 34], "unsupport": 1, "field": [1, 2, 3, 8, 9, 11, 15, 19, 25, 30], "name": [1, 2, 3, 6, 7, 9, 11, 13, 14, 15, 16, 17, 19, 23, 24, 25, 26, 30, 34], "mean": [1, 2, 3, 9, 14], "we": [1, 2, 6, 7, 8, 9, 10, 11, 13, 14, 15, 23, 24, 26, 27, 30, 33, 34], "won": [1, 7, 8, 26, 30], "t": [1, 2, 3, 6, 7, 8, 9, 10, 11, 13, 14, 23, 24, 26, 27, 30, 33, 34], "support": [1, 2, 3, 6, 8, 9, 11, 12, 13, 19, 24, 25, 30, 33, 34], "all": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 24, 25, 26, 30], "avail": [1, 2, 3, 8, 9, 10, 11, 13, 15, 19, 23, 24, 25, 26, 30, 34], "pass": [1, 2, 6, 8, 10, 27, 33], "down": [1, 9, 12, 19, 23], "raidconfigur": 1, "under": [1, 2, 11, 13, 22, 25], "dev": [1, 2, 15], "which": [1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 20, 23, 24, 25, 26, 34], "constitut": 1, "modelregex": 1, "regular": [1, 2, 3, 9, 13], "express": [1, 2, 3, 11], "filter": [1, 17], "model": [1, 17], "nameregex": 1, "group": [1, 2, 3], "selector": [1, 8, 9, 34], "must": [1, 2, 3, 6, 8, 9, 13, 19, 23, 25, 26, 27, 28, 31, 34], "fit": [1, 6, 8], "": [1, 2, 3, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 23, 24, 26, 30, 33, 34], "label": [1, 2, 7, 9, 10, 15, 19, 22, 23, 26], "have": [1, 2, 3, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 24, 25, 26, 30, 33, 34], "describ": [1, 2, 3, 4, 7, 9, 10, 13, 14, 16, 17, 19, 24, 25, 34], "e": [1, 2, 3, 9, 30, 34], "g": [1, 2, 3, 10, 14, 34], "co": [1, 2, 3], "locat": [1, 2, 3, 13, 17, 24, 30], "same": [1, 2, 3, 7, 8, 9, 10, 11, 13, 14, 19, 25, 26, 27], "zone": [1, 10, 12, 19], "etc": [1, 2, 3, 13, 15, 26], "some": [1, 2, 3, 6, 8, 9, 11, 13, 23, 27, 30, 33], "other": [1, 2, 3, 6, 8, 10, 11, 12, 13, 15, 16, 17, 19, 23, 26, 27, 30], "anti": [1, 2, 3], "avoid": [1, 2, 6, 30, 33], "put": [1, 6], "The": [1, 2, 3, 6, 7, 8, 9, 10, 12, 13, 15, 16, 17, 19, 26, 27, 29, 30], "satisfi": [1, 2, 3], "choos": [1, 2, 3, 9, 12, 19], "violat": [1, 2, 3], "one": [1, 2, 3, 6, 8, 9, 11, 13, 14, 17, 19, 20, 23, 25, 30, 34], "most": [1, 2, 3, 6, 7, 9, 10, 11, 15, 19, 26], "greatest": [1, 2, 3], "sum": [1, 2, 3], "weight": [1, 2, 3], "each": [1, 2, 3, 8, 9, 10, 11, 13, 14, 16, 17, 19, 25, 26, 34], "meet": [1, 2, 3, 19, 26], "requiredduringschedul": [1, 2, 3], "comput": [1, 2, 3, 10, 17], "iter": [1, 2, 3], "through": [1, 2, 3, 8, 9, 11, 16, 17, 19], "element": [1, 2, 3], "ad": [1, 2, 3, 6, 9, 12, 16], "correspond": [1, 2, 3, 16, 17], "highest": [1, 2, 3], "If": [1, 2, 3, 6, 7, 9, 10, 11, 13, 14, 15, 19, 25, 29, 30, 33], "met": [1, 2, 3, 15, 19, 24], "time": [1, 2, 3, 6, 11, 13, 14, 23, 24, 27], "onto": [1, 2, 3], "ceas": [1, 2, 3], "point": [1, 2, 3, 8, 10, 14, 15, 19, 25, 30], "execut": [1, 2, 3, 11, 13, 14, 19, 24, 25, 26, 29], "due": [1, 2, 3, 13, 19, 20, 24], "system": [1, 2, 3, 10, 14, 25, 34], "try": [1, 2, 3, 30], "eventu": [1, 2, 3], "evict": [1, 2, 3], "its": [1, 2, 3, 7, 9, 10, 13, 14, 16, 17, 19], "empti": [1, 2, 3, 9, 24], "term": [1, 2, 3], "implicit": [1, 2, 3], "0": [1, 2, 3, 6, 8, 9, 10, 11, 13, 15, 16, 17, 19, 23, 24, 25, 26, 27, 30], "op": [1, 2, 3, 9, 14, 19, 24], "A": [1, 2, 3, 7, 8, 9, 10, 11, 15, 16, 17, 19, 34], "null": [1, 2, 3, 15], "also": [1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 30], "associ": [1, 2, 3, 6, 9, 13, 14, 16, 17], "integ": [1, 2, 3], "rang": [1, 2, 3, 15, 16, 17], "1": [1, 2, 3, 6, 7, 8, 9, 11, 13, 14, 15, 16, 17, 19, 23, 24, 25, 26, 27], "100": [1, 2, 3, 13, 24], "kei": [1, 2, 3, 8, 9, 13, 19, 30], "oper": [1, 2, 3, 4, 5, 8, 13, 14, 19, 20, 22, 23, 24, 25, 26, 27, 30, 31, 33], "relat": [1, 2, 3, 8, 12, 19, 30], "appli": [1, 2, 3, 6, 7, 9, 10, 11, 13, 14, 15, 19, 26, 29, 30, 34], "relationship": [1, 2, 3], "set": [1, 2, 3, 6, 8, 11, 12, 13, 15, 19, 24, 25, 26, 29, 30], "valid": [1, 2, 3, 11, 13, 15, 25, 34], "notin": [1, 2, 3], "exist": [1, 2, 3, 9, 13, 14, 19, 25, 27, 30, 34], "doesnotexist": [1, 2, 3], "gt": [1, 2, 3], "lt": [1, 2, 3], "non": [1, 2, 3, 16, 19, 24, 25], "singl": [1, 2, 3, 6, 9, 11, 13, 19], "interpret": [1, 2, 3], "replac": [1, 2, 3, 9, 12, 14, 15, 19, 21, 24, 30, 34], "strateg": [1, 2, 3], "merg": [1, 2, 3, 6, 8, 19, 24, 25, 27], "patch": [1, 2, 3, 14, 19, 24, 25, 34], "ORed": [1, 2, 3], "them": [1, 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 16, 19, 26, 30, 34], "ANDed": [1, 2, 3], "topologyselectorterm": [1, 2, 3], "implement": [1, 2, 3, 6, 19], "subset": [1, 2, 3, 19, 30], "ha": [1, 2, 3, 6, 8, 9, 10, 16, 19, 24, 27], "when": [1, 2, 3, 6, 7, 8, 9, 10, 13, 14, 15, 17, 19, 21, 22, 24, 25, 26, 27, 30, 31, 33], "multipl": [1, 2, 3, 6, 8, 9, 13, 14, 18], "intersect": [1, 2, 3], "weightedpodaffinityterm": [1, 2, 3], "per": [1, 2, 3, 9], "find": [1, 2, 3, 5, 9, 11, 15, 25, 33, 34], "queri": [1, 2, 3], "over": [1, 2, 3, 7, 10, 19, 23, 25], "case": [1, 2, 3, 8, 9, 14, 16, 19, 21, 23, 26, 30, 33, 34], "matchlabelkei": [1, 2, 3], "select": [1, 2, 3, 6, 8, 9, 19], "taken": [1, 2, 3, 8, 24, 25], "consider": [1, 2, 3], "lookup": [1, 2, 3, 14], "incom": [1, 2, 3], "those": [1, 2, 3, 7, 9, 10, 26], "don": [1, 2, 3, 6, 7, 8, 10, 11, 30], "ignor": [1, 2, 3, 23], "default": [1, 2, 3, 8, 9, 10, 11, 13, 19, 23, 24, 26, 29, 30], "forbidden": [1, 2, 3], "both": [1, 2, 3, 8, 9, 11, 16, 17, 24], "isn": [1, 2, 3, 11], "alpha": [1, 2, 3, 7, 10, 27], "enabl": [1, 2, 3, 8, 9, 10, 13, 16, 17, 19, 20, 22, 25, 29], "matchlabelkeysinpodaffin": [1, 2, 3], "featur": [1, 2, 3, 6, 24, 26], "gate": [1, 2, 3, 24], "mismatchlabelkei": [1, 2, 3], "namespac": [1, 2, 3, 9, 11, 13, 14, 19, 24, 26, 34], "union": [1, 2, 3], "ones": [1, 2, 3, 8, 16, 34], "static": [1, 2, 3, 7, 10, 14, 26], "topologykei": [1, 2, 3, 19], "run": [1, 2, 3, 4, 6, 7, 10, 11, 12, 13, 14, 15, 19, 23, 24, 25, 26, 34], "whose": [1, 2, 3, 9], "ani": [1, 2, 3, 6, 8, 10, 11, 14, 16, 17, 24, 26, 27], "allow": [1, 2, 3, 7, 9, 11, 15, 16, 17, 19, 22, 25, 26, 33], "map": [1, 2, 3, 13], "pair": [1, 2, 3, 8, 9], "equival": [1, 2, 3, 8], "onli": [1, 2, 3, 7, 9, 14, 16, 17, 19, 25, 26, 27, 30, 34], "rel": [1, 2, 3], "given": [1, 2, 3, 16, 23, 30], "attach": [1, 2, 3, 9, 10, 14, 23, 30, 31], "taint": [1, 2, 3, 7, 10], "tripl": [1, 2, 3], "effect": [1, 2, 3, 19], "indic": [1, 2, 3], "noschedul": [1, 2, 3, 7, 10, 19], "prefernoschedul": [1, 2, 3], "noexecut": [1, 2, 3], "combin": [1, 2, 3], "equal": [1, 2, 3, 9, 19, 26], "wildcard": [1, 2, 3, 15], "so": [1, 2, 3, 6, 8, 9, 10, 11, 15, 16, 17, 19, 26, 34], "can": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 23, 25, 26, 30, 31, 33], "particular": [1, 2, 3, 8, 9, 11, 19, 25, 27], "categori": [1, 2, 3], "tolerationsecond": [1, 2, 3], "period": [1, 2, 3, 14], "otherwis": [1, 2, 3, 6, 15, 16, 27], "By": [1, 2, 3, 8, 10, 11, 26, 30], "forev": [1, 2, 3], "do": [1, 2, 3, 6, 9, 13, 15, 16, 17, 22, 31, 33, 34], "zero": [1, 2, 3, 9, 25], "neg": [1, 2, 3], "treat": [1, 2, 3], "immedi": [1, 2, 3, 26], "just": [1, 2, 3, 6, 7, 9, 10], "observ": [1, 2, 3, 4, 11, 25], "current": [1, 2, 3, 9, 11, 12, 15, 16, 17, 19, 25, 30, 33], "state": [1, 2, 3, 4, 9, 11, 13, 15, 19, 23, 25, 30], "hold": [1, 2, 3], "tune": [1, 7, 10, 12], "observedgener": [1, 2, 3], "recent": [1, 2, 3, 6], "gener": [1, 2, 3, 6, 7, 8, 9, 10, 13, 14, 15, 25, 34], "lasttransitiontim": [1, 2, 3], "last": [1, 2, 3, 6], "transit": [1, 2, 3], "anoth": [1, 2, 3, 8, 14, 33], "messag": [1, 2, 3, 9, 13, 25], "human": [1, 2, 3, 19], "readabl": [1, 2, 3, 16], "detail": [1, 2, 3, 9, 13, 15, 19, 26], "about": [1, 2, 3, 6, 7, 8, 9, 10, 11, 17, 26], "wa": [1, 2, 3, 6, 9, 11, 13, 14, 16, 23, 24, 34], "base": [1, 2, 3, 6, 11, 26], "upon": [1, 2, 3, 8, 16, 17], "For": [1, 2, 3, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 19, 22, 26], "instanc": [1, 2, 3, 9, 10, 11, 13, 14, 15, 16, 17, 19], "12": [1, 2, 3, 6, 13, 24, 27], "x": [1, 2, 3, 27], "9": [1, 2, 3, 23, 24, 25, 27, 34], "out": [1, 2, 3, 5, 9, 12, 14, 19, 25, 34], "date": [1, 2, 3, 6, 11, 13, 19, 27, 34], "respect": [1, 2, 3, 10], "reason": [1, 2, 3, 11], "fals": [1, 2, 3, 11, 13, 15, 17, 19, 24], "unknown": [1, 2, 3], "tunedcontain": 1, "tunednod": 1, "scyllaclusterlist": 2, "agentrepositori": 2, "repositori": [2, 6, 9, 34], "pull": [2, 11, 30, 34], "agent": [2, 11, 13, 19], "imag": [2, 4, 6, 10, 14, 17, 25, 26, 27, 34], "agentvers": [2, 9, 19, 24, 26], "manag": [2, 3, 8, 10, 12, 14, 16, 17, 23, 24, 26, 27, 30, 34], "design": 2, "automaticorphanednodecleanup": [2, 19, 20], "orphan": 2, "cleanup": [2, 21, 25], "perform": [2, 7, 9, 10, 12, 20], "task": [2, 7, 9, 12, 19, 24], "instal": [2, 3, 6, 9, 12, 13, 14, 15, 16, 17, 19, 30, 32, 34], "cpuset": [2, 9, 19], "determin": [2, 3, 6, 30], "cpu": [2, 7, 9, 10, 11, 19, 24, 26], "pin": [2, 26, 34], "max": [2, 9, 19], "developermod": [2, 9, 24], "develop": [2, 7, 10, 13, 15], "mode": [2, 3, 7, 10, 13, 17, 21, 25, 30], "dnsdomain": [2, 3, 15], "dn": [2, 3, 6, 8, 9, 15, 19, 22, 23], "domain": [2, 3, 19], "reachabl": [2, 3, 8, 15], "These": [2, 7, 8, 10, 26, 34], "up": [2, 6, 8, 11, 12, 14, 15, 19, 23, 25, 26, 34], "infrastructur": [2, 16, 17, 19], "like": [2, 3, 6, 9, 12, 13, 14, 15, 23, 26, 27, 30], "certif": [2, 9, 11, 15, 24], "experiment": [2, 12, 15, 26, 34], "reli": 2, "behaviour": [2, 6], "expos": [2, 3, 12, 19], "servic": [2, 3, 9, 11, 14, 15, 17, 22, 23, 33], "externalse": [2, 19], "extern": [2, 3, 8, 11, 14, 15, 23, 30], "seed": 2, "propag": [2, 8, 9, 14, 19], "binari": [2, 19, 30], "startup": [2, 19], "paramet": [2, 19], "provid": [2, 5, 7, 8, 9, 10, 11, 15, 16, 19, 26, 31, 33], "forceredeploymentreason": [2, 19, 24], "forc": [2, 10], "roll": [2, 9, 11, 12, 14, 19, 24, 25, 34], "uniqu": [2, 9, 19], "behavior": 2, "logic": [2, 6, 8], "refer": [2, 3, 7, 9, 10, 11, 12, 14, 15, 16, 17, 19, 27, 34], "config": [2, 3, 9, 10, 13, 16, 17, 19, 30], "scyllaarg": 2, "append": [2, 9], "4": [2, 7, 9, 10, 11, 13, 19, 24, 25, 26, 27], "2": [2, 8, 9, 10, 11, 13, 14, 16, 17, 19, 22, 23, 24, 25, 26, 27], "sysctl": [2, 9, 19], "initi": [2, 14, 19], "exampl": [2, 3, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 19, 22, 24, 25, 26, 30, 34], "f": [2, 7, 9, 10, 11, 13, 14, 15, 16, 19, 34], "aio": [2, 9, 19], "nr": [2, 9, 19], "232323": 2, "tag": [2, 11, 14, 24, 25, 27, 34], "port": [2, 9, 11, 14, 15, 16, 23, 24, 34], "number": [2, 6, 9, 34], "bind": [2, 3, 10], "writeisol": [2, 9], "isol": [2, 9], "level": [2, 9, 13], "dc": [2, 13, 19], "glob": 2, "pattern": [2, 9, 11, 30], "dc1": [2, 19], "otherdc": 2, "includ": [2, 3, 6, 11, 17, 31, 33], "exclud": 2, "interv": [2, 13], "3d2h10m": 2, "unit": [2, 6], "d": [2, 15, 19, 34], "h": [2, 9], "m": [2, 13], "keyspac": [2, 9, 13, 24, 25], "tabl": [2, 24, 27], "table_prefix_": 2, "format": [2, 10, 13, 17, 25], "ex": [2, 10], "s3": [2, 13, 24], "my": [2, 8, 13], "bucket": [2, 13], "part": [2, 26], "need": [2, 6, 7, 8, 9, 10, 11, 14, 15, 16, 17, 19, 23, 24, 25, 26, 30, 33, 34], "differ": [2, 3, 7, 8, 9, 11, 13, 16, 17, 19, 26], "being": [2, 3, 8, 9, 13, 19, 22, 23, 25, 27], "upload": [2, 6], "data": [2, 3, 9, 10, 13, 15, 19, 23, 24, 25, 28, 34], "alphanumer": 2, "dash": [2, 6], "dot": 2, "charact": 2, "moment": 2, "gc": 2, "numretri": 2, "how": [2, 5, 6, 7, 8, 10, 11, 13, 15, 23, 24, 30, 33], "mani": [2, 3, 11, 15, 26, 30], "retri": [2, 13, 25], "befor": [2, 6, 14, 15, 25, 27, 30, 33, 34], "fail": [2, 9, 13, 15, 23, 24, 29], "ratelimit": 2, "megabyt": 2, "mib": 2, "second": [2, 9], "rate": [2, 9], "retent": [2, 13], "store": [2, 3, 23, 24], "snapshotparallel": 2, "snapshot": [2, 3, 24, 25], "parallel": [2, 24, 25], "global": 2, "5": [2, 6, 8, 9, 13, 19, 24, 25, 26, 27], "n": [2, 7, 9, 10, 11, 13, 14, 15, 19, 22, 23, 24, 25, 27, 30, 34], "startdat": 2, "start": [2, 6, 7, 9, 13, 16, 24, 25, 26], "rfc3339": 2, "now": [2, 6, 7, 9, 10, 13, 14, 16, 17, 19], "durat": [2, 13, 24, 30], "uploadparallel": 2, "cassandra": [2, 7, 10], "rackdc": [2, 9], "file": [2, 6, 9, 10, 11, 14, 16, 30, 33, 34], "rackspec": 2, "member": [2, 3, 9, 11, 13, 14, 15, 19, 24, 25, 26], "restrict": [2, 3], "scyllaagentconfig": 2, "custom": [2, 3, 8, 13, 15, 16, 17], "scyllaconfig": 2, "yaml": [2, 7, 9, 10, 11, 13, 14, 15, 16, 19, 30, 34], "underli": [2, 3, 25], "consum": [2, 3], "resourceclaim": [2, 3], "dynamicresourcealloc": [2, 3], "immut": [2, 3], "It": [2, 3, 6, 7, 8, 9, 10, 11, 16, 17, 19, 25], "maximum": [2, 3, 7, 10], "amount": [2, 3], "kubernet": [2, 3, 5, 7, 8, 11, 12, 14, 15, 27, 30, 33], "doc": [2, 3, 5, 7, 9, 24, 26, 33], "concept": [2, 3], "minimum": [2, 3], "omit": [2, 3, 16], "explicitli": [2, 3], "exce": [2, 3], "entri": [2, 3, 9], "podspec": [2, 3], "make": [2, 3, 6, 9, 10, 11, 13, 14, 15, 19, 23, 24, 27, 30, 33, 34], "insid": [2, 3, 7, 9, 10, 22], "mount": [2, 7, 9, 10, 30], "within": [2, 8, 26, 30], "mountpath": 2, "mountpropag": 2, "host": [2, 6, 13, 15, 19, 23], "wai": [2, 9, 10, 13, 14, 15, 30], "around": [2, 26], "mountpropagationnon": 2, "beta": [2, 3, 8, 27], "10": [2, 9, 11, 13, 14, 16, 17, 19, 23, 27], "readonli": 2, "read": [2, 6, 7, 9, 10, 11, 14], "write": [2, 6, 9], "unspecifi": [2, 3], "subpath": 2, "root": [2, 25], "subpathexpr": 2, "expand": 2, "behav": 2, "similarli": [2, 11, 30], "environ": [2, 6, 8, 9, 11, 14, 19, 30], "variabl": [2, 6, 19, 30], "var_nam": 2, "mutual": 2, "exclus": [2, 8, 26], "affin": [2, 3, 20], "capac": [2, 3, 7, 10, 11, 19, 24, 26], "size": [2, 10, 17, 23, 24], "persist": [2, 3, 10, 13], "storageclassnam": [2, 3, 19], "storageclass": [2, 3, 19], "access": [2, 3, 5, 6, 8, 13, 24], "aw": [2, 7, 8, 16], "kubelet": [2, 7, 10, 26], "machin": [2, 7, 9, 10, 15, 17, 30], "azur": 2, "ceph": 2, "share": [2, 16, 17, 26], "lifetim": 2, "mysql": 2, "pd": [2, 10, 17], "readm": 2, "popul": [2, 3, 9], "interfac": [2, 3, 10, 17], "handl": [2, 10], "certain": [2, 9], "driver": [2, 3, 7, 8, 9, 10], "downward": 2, "temporari": 2, "directori": [2, 6, 30, 34], "lifecycl": [2, 6, 19], "ti": [2, 13, 23, 24], "delet": [2, 9, 13, 14, 23, 25, 34], "remov": [2, 6, 9, 11, 14, 19, 20, 22, 25, 30, 34], "while": [2, 3, 9], "b": [2, 6, 10, 17, 19, 22], "normal": [2, 19, 23], "restor": [2, 21, 25, 34], "track": [2, 6, 9, 13], "c": [2, 9, 17, 19, 23, 24], "class": [2, 3, 8, 9, 26], "dynam": [2, 3, 7, 10], "provis": [2, 7, 8, 9, 10, 11, 19], "see": [2, 3, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 24, 26], "ephemeralvolumesourc": 2, "inform": [2, 9, 15, 16, 17, 19, 25, 31, 33], "connect": [2, 8, 9, 13, 16], "between": [2, 3, 9, 16, 17], "vendor": 2, "longer": [2, 6, 9, 10, 19, 23, 24], "than": [2, 3, 6, 8, 9, 14, 23, 30], "individu": [2, 7, 10], "light": 2, "meant": 2, "document": [2, 3, 6, 7, 8, 9, 10, 11, 13, 16, 17, 19], "fibr": 2, "channel": [2, 14, 16], "exec": [2, 9, 13, 19, 23, 24, 30], "plugin": [2, 30], "depend": [2, 6, 8, 14, 22, 23, 26, 27, 30], "gce": 2, "revis": [2, 15], "deprec": 2, "To": [2, 3, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 19, 22, 23, 24, 25, 29, 31, 33, 34], "repo": [2, 6, 11, 14, 34], "initcontain": [2, 14], "clone": [2, 9], "pre": 2, "directli": [2, 8, 17], "privileg": 2, "thing": [2, 9], "NOT": 2, "todo": 2, "jonesdl": 2, "who": 2, "dns_label": 2, "overview": [2, 28], "work": [2, 5, 6, 7, 10, 11, 14, 16, 17, 19, 26, 27], "persistentvolumeclaimvolumesourc": 2, "photoncontrol": 2, "portworx": 2, "rado": 2, "block": [2, 10, 33], "devic": [2, 7, 10, 26], "vsphere": 2, "filesystem": [2, 3, 7, 10, 22], "you": [2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 23, 24, 25, 30, 33, 34], "want": [2, 6, 7, 8, 9, 10, 11, 13, 16, 17, 24, 34], "tip": 2, "ensur": [2, 6, 9, 14], "ext4": 2, "xf": [2, 7, 10, 19], "ntf": 2, "implicitli": 2, "prevent": 2, "error": [2, 3, 9, 10, 13, 25, 30], "compromis": 2, "partit": 2, "sda1": 2, "sda": 2, "leav": [2, 19, 23, 26], "volumeid": 2, "id": [2, 13, 16, 19, 23, 24], "amazon": [2, 7, 18, 19], "eb": 2, "cachingmod": 2, "cach": 2, "none": [2, 11, 14, 23], "disknam": 2, "blob": 2, "diskuri": 2, "uri": 2, "expect": [2, 3, 19, 34], "account": [2, 6, 10], "dedic": [2, 8, 11, 13, 16, 17, 19, 26, 30, 31], "here": [2, 3, 6, 9, 30, 34], "secretnam": 2, "sharenam": 2, "monitor": [2, 3, 7, 10, 12, 19, 27], "collect": [2, 14, 15, 31], "rather": [2, 27], "full": [2, 7, 9, 10, 13, 14, 23, 25], "tree": 2, "secretfil": 2, "ring": [2, 19], "user": [2, 3, 6, 9, 10, 12, 13, 14, 15, 22, 24, 25, 26, 30, 33, 34], "authent": [2, 9, 30], "admin": [2, 15, 30], "add": [2, 9, 11, 13, 14, 17, 19, 22, 23, 24, 34], "uid": [2, 14], "openstack": 2, "identifi": [2, 3, 23, 24], "defaultmod": 2, "bit": [2, 9, 11], "permiss": [2, 10, 13, 14], "octal": 2, "0000": [2, 13], "0777": 2, "decim": 2, "511": 2, "accept": [2, 3, 7, 27], "json": [2, 3, 14, 19, 24], "0644": 2, "affect": [2, 30], "might": [2, 8, 14, 23], "conflict": [2, 6], "fsgroup": 2, "result": [2, 9, 14], "referenc": [2, 3], "content": [2, 3, 9, 10, 11, 24, 27], "unlist": 2, "present": [2, 13, 16], "unless": [2, 15, 30], "mark": 2, "whether": [2, 3, 8, 11, 26, 30], "absolut": 2, "consult": [2, 13], "your": [2, 7, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 23, 24, 25, 26, 29, 30, 33, 34], "correct": [2, 13, 15], "regist": [2, 13, 14, 24], "sensit": [2, 30], "complet": [2, 6, 9, 15, 23], "nodepublishvolum": 2, "nodeunpublishvolum": 2, "call": [2, 9, 10, 24, 26, 31, 33, 34], "downwardapivolumefil": 2, "utf": 2, "8": [2, 10, 13, 15, 17, 27], "encod": 2, "first": [2, 6, 7, 9, 10, 11, 13, 14, 15, 24, 25, 34], "memori": [2, 9, 11, 19, 24, 26], "fieldpath": 2, "written": 2, "containernam": 2, "env": [2, 9, 30], "var": [2, 13], "divisor": 2, "output": [2, 6, 9, 13, 14, 17, 19, 24], "medium": 2, "what": [2, 3, 6, 8, 9, 11, 13, 14, 15, 25, 30, 31], "back": [2, 3, 8, 22, 23, 25], "sizelimit": 2, "total": [2, 9], "applic": [2, 11, 26], "usag": [2, 9], "would": [2, 6, 9, 13, 17, 23], "nil": 2, "undefin": 2, "Will": 2, "stand": 2, "alon": 2, "pvc": [2, 3, 20], "embed": [2, 30, 31], "owner": [2, 3], "togeth": [2, 7, 10], "concaten": 2, "too": 2, "long": 2, "own": [2, 7, 10, 11, 19, 23], "unrel": [2, 19], "mistak": 2, "until": [2, 3, 9, 11, 14, 24, 25, 34], "onc": [2, 3, 6, 7, 9, 10, 11, 13, 16, 17, 25, 34], "necessari": [2, 7, 9, 10, 15, 16, 17, 19, 30], "manual": [2, 3, 9, 10, 14, 15, 17, 19, 24, 25, 30, 33, 34], "reconstruct": 2, "broken": 2, "made": [2, 6, 8, 27], "after": [2, 3, 6, 7, 9, 10, 11, 13, 23], "been": [2, 8, 9], "copi": [2, 3, 9, 30], "No": [2, 3], "entir": [2, 3, 8, 9, 19, 26], "unchang": [2, 3], "get": [2, 3, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 19, 23, 24, 25, 30, 34], "templat": [2, 3, 9, 14, 15, 19, 24, 34], "accessmod": [2, 3], "either": [2, 3, 9, 11, 13], "volumesnapshot": [2, 3], "provision": [2, 3, 16, 17, 19], "new": [2, 3, 6, 9, 10, 12, 13, 14, 15, 16, 19, 23, 25, 26, 27, 34], "anyvolumedatasourc": [2, 3], "core": [2, 3, 9, 10, 26], "succe": [2, 3, 22], "function": [2, 3, 19, 27, 33], "thei": [2, 3, 8, 9, 13, 19, 30], "backward": [2, 3, 14, 34], "compat": [2, 3], "There": [2, 3, 30, 33, 34], "three": [2, 3, 6, 11, 13], "import": [2, 3, 9, 10, 27], "two": [2, 3, 6, 8, 11, 13, 14, 16, 17, 19, 24, 25, 26, 34], "well": [2, 3, 6, 7, 9, 10, 13, 14, 15], "disallow": [2, 3], "drop": [2, 3], "preserv": [2, 3, 34], "crossnamespacevolumedatasourc": [2, 3], "recovervolumeexpansionfailur": [2, 3], "lower": [2, 3, 14], "previou": [2, 3, 14, 25], "still": [2, 3, 30], "higher": [2, 3], "record": [2, 3, 8, 15], "consid": [2, 3, 14], "volumeattributesclassnam": [2, 3], "volumeattributesclass": [2, 3], "attribut": [2, 3], "purpos": [2, 3, 10, 30], "reset": [2, 3], "unbound": [2, 3], "persistentvolum": [2, 3, 7, 9, 10], "pend": [2, 3, 23], "reflect": [2, 3], "modifyvolumestatu": [2, 3], "volumemod": [2, 3], "impli": [2, 3, 8], "volumenam": [2, 3], "apigroup": [2, 3, 14], "third": [2, 3, 15], "parti": [2, 3, 15], "note": [2, 3, 9, 13, 15, 34], "gatewai": [2, 3], "referencegr": [2, 3], "lun": 2, "target": [2, 13, 16, 24, 26, 34], "targetwwn": 2, "worldwid": 2, "wwn": 2, "wwid": 2, "world": 2, "wide": [2, 13], "simultan": 2, "script": [2, 9, 10, 26], "extra": [2, 9, 30], "command": [2, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 19, 23, 24, 29, 30], "datasetnam": 2, "dataset": 2, "datasetuuid": 2, "uuid": [2, 14], "pdname": 2, "suppli": [2, 30], "subdirectori": 2, "url": [2, 11], "commit": [2, 13, 27], "hash": [2, 17], "topologi": [2, 19], "symlink": [2, 34], "follow": [2, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 24, 25, 27, 29, 34], "link": [2, 6, 29], "real": [2, 15], "chapauthdiscoveri": 2, "discoveri": 2, "chap": 2, "chapauthsess": 2, "session": [2, 9], "initiatornam": 2, "iscsiinterfac": 2, "portal": 2, "iqn": 2, "qualifi": 2, "transport": 2, "tcp": [2, 8, 11, 14, 17, 23], "ip": [2, 8, 9, 11, 14, 15, 17, 19, 23, 29], "ip_addr": 2, "typic": 2, "860": 2, "3260": 2, "targetport": 2, "export": [2, 7, 10, 30], "hostnam": [2, 8, 19], "address": [2, 8, 15, 17, 19, 23], "claimnam": 2, "pdid": 2, "photon": 2, "along": [2, 9], "trustbundl": 2, "auto": [2, 9], "clustertrustbundleproject": 2, "signer": 2, "aggress": 2, "pem": 2, "esoter": 2, "inter": [2, 8, 18, 19], "comment": 2, "header": 2, "strip": 2, "dedupl": 2, "order": [2, 6, 8, 9, 10, 13, 19, 34], "arbitrari": [2, 3], "signernam": 2, "unset": 2, "noth": [2, 14], "everyth": [2, 6, 7, 9, 10, 11, 25], "aren": [2, 27], "bundl": 2, "unifi": 2, "downwardapivolum": 2, "audienc": 2, "intend": [2, 3], "token": [2, 19, 23, 30], "recipi": 2, "itself": [2, 6, 11, 13, 22], "apiserv": [2, 33], "expirationsecond": 2, "As": [2, 6, 7, 10, 13, 16, 19, 24, 30], "approach": 2, "expir": 2, "proactiv": 2, "rotat": 2, "older": 2, "80": [2, 11], "percent": 2, "live": [2, 22], "24": [2, 19, 24], "hour": 2, "least": [2, 6, 10, 11, 19, 26, 30], "minut": [2, 25], "registri": [2, 22], "separ": [2, 6, 7, 8, 10, 14, 16, 26], "comma": 2, "act": 2, "central": 2, "tenant": 2, "backend": [2, 8], "serivceaccount": 2, "keyr": 2, "rbduser": 2, "pool": [2, 7, 10, 17, 19, 23, 26], "overrid": [2, 9], "protectiondomain": 2, "protect": 2, "login": 2, "sslenabl": 2, "flag": [2, 16, 17, 20, 24, 30, 34], "disabl": [2, 3, 10, 11, 17, 22, 24, 25, 29], "ssl": [2, 13, 15], "storagemod": 2, "thickprovis": 2, "thinprovis": 2, "storagepool": 2, "obtain": [2, 10], "credenti": [2, 10, 13, 15, 24], "attempt": [2, 13], "volumenamespac": 2, "mirror": 2, "tighter": 2, "integr": [2, 6, 12, 19], "storagepolicyid": 2, "polici": [2, 6, 7, 8, 10, 11, 26], "spbm": 2, "profil": 2, "storagepolicynam": 2, "volumepath": 2, "vmdk": 2, "publish": [2, 27], "broadcast": 2, "broadcast_rpc_address": 2, "broadcast_address": 2, "sourcetyp": 2, "everi": [2, 3, 8, 9, 19, 25, 27], "creation": [2, 3, 7, 10, 13, 27], "ingressclassnam": [2, 3, 15], "allocateloadbalancernodeport": [2, 8], "check": [2, 8, 9, 12, 13, 14, 23, 24, 25, 26, 30, 34], "corev1": 2, "semant": [2, 25], "externaltrafficpolici": [2, 8], "internaltrafficpolici": [2, 8], "loadbalancerclass": [2, 8], "failurestrategi": 2, "failur": [2, 22, 23, 25], "happen": [2, 9, 25], "pollinterv": [2, 13], "often": [2, 15, 33], "poll": 2, "increas": [2, 9], "sent": 2, "overal": 2, "spent": 2, "localobjectrefer": 2, "enough": [2, 30], "let": [2, 7, 10, 11, 13, 19, 30], "dnspolici": 2, "hostnetwork": [2, 9, 33], "sdn": [2, 33], "failfast": 2, "stop": 2, "intens": [2, 24], "shard": 2, "job": [2, 9, 27], "adjust": [2, 9, 15, 16, 17, 19, 30], "max_repair_ranges_in_parallel": 2, "log": [2, 6, 9, 13, 25], "load": [2, 8, 19, 22, 23], "slightli": [2, 15], "faster": 2, "impact": 2, "granular": 2, "resum": 2, "row": 2, "master": [2, 6, 27], "below": [2, 9, 13, 14, 15, 16, 17, 19, 24, 26], "replica": [2, 25], "take": [2, 7, 9, 10, 23, 24, 25, 26, 30], "possibl": [2, 23], "replic": [2, 3, 9], "factor": [2, 9, 30], "rf": 2, "formula": 2, "calcul": 2, "6": [2, 9, 24, 26, 27], "3": [2, 6, 7, 9, 11, 13, 19, 24, 25, 26, 27], "smalltablethreshold": 2, "small": [2, 9, 13], "threshold": 2, "gib": [2, 11], "tib": 2, "rollout": [2, 3, 9, 14, 15, 34], "finish": [2, 3, 9, 24], "look": [2, 3, 6, 9, 11, 14, 19, 30], "progress": [2, 3, 13, 15, 19, 24], "degrad": [2, 3, 15, 19, 24], "managerid": 2, "mutat": [2, 3, 34], "ongo": 2, "procedur": [2, 12, 19, 23, 24, 25, 34], "identif": 2, "aspect": [2, 3], "struct": [2, 3], "direct": [2, 3, 8, 9, 15, 17], "foostatu": [2, 3], "foo": [2, 3, 24], "known": [2, 3, 16, 28], "patchmergekei": [2, 3], "patchstrategi": [2, 3], "listtyp": [2, 3], "listmapkei": [2, 3], "metav1": [2, 3], "omitempti": [2, 3], "protobuf": [2, 3], "byte": [2, 3], "rep": [2, 3], "programmat": [2, 3], "produc": [2, 3], "guarante": [2, 3, 10, 26], "consist": [2, 3, 11, 13, 19, 24, 26], "across": [2, 3, 19, 26], "becaus": [2, 3, 8, 9, 13, 19, 23, 30], "abil": [2, 3], "deconflict": [2, 3], "regex": [2, 3], "dns1123subdomainfmt": [2, 3], "qualifiednamefmt": [2, 3], "currentnod": 2, "currentrack": 2, "datasnapshottag": 2, "fromvers": 2, "systemsnapshottag": 2, "tovers": 2, "scylladbmonitoringlist": 3, "addit": [3, 8, 11, 13, 14, 17, 34], "scrape": [3, 11], "datacent": [3, 9, 11, 12, 13, 16, 17, 23, 24, 26, 30], "were": [3, 11], "remot": 3, "without": [3, 6, 8, 10, 11, 15, 30], "platform": [3, 8, 9, 15, 16, 17, 18], "ui": 3, "servingcertsecretnam": 3, "secret": [3, 9, 11, 15, 19, 30], "cert": [3, 14], "self": [3, 9, 11], "sign": [3, 9, 11, 14], "ca": [3, 11, 15], "insecureenableanonymousaccess": 3, "web": [3, 10], "unstructur": 3, "tool": [3, 6, 7, 15, 16, 17, 19, 30, 31], "retriev": [3, 9, 17, 30], "queryabl": 3, "modifi": [3, 6, 9, 10, 17, 25, 33], "guid": [3, 7, 9, 10, 11, 13, 14, 16, 17, 19, 34], "organ": 3, "categor": 3, "persistentvolumeclaim": 3, "volum": [3, 16, 17, 19, 30], "sourc": [3, 8, 11, 12, 13, 16, 17, 24, 34], "csi": [3, 7, 10], "network": [3, 6, 8, 12, 18, 23, 26, 33], "scyllaoperatorconfiglist": 4, "scyllautilsimag": 4, "util": [4, 19], "scylla": [5, 8, 14, 15, 16, 17, 20, 22, 24, 26, 27, 30, 31, 33], "crd": [5, 6, 9, 11, 13, 14, 26, 34], "adher": 5, "standard": [5, 10, 17, 33], "style": 5, "authn": 5, "authz": 5, "scylladb": [5, 6, 8, 9, 11, 12, 14, 15, 24, 26, 27, 30, 31, 34], "com": [5, 6, 7, 8, 9, 10, 11, 14, 15, 19, 24, 26, 30, 34], "13": [6, 13, 27], "sure": [6, 9, 10, 11, 13, 14, 19, 23, 24, 27, 30, 33, 34], "gopath": 6, "home": 6, "kustom": 6, "v3": 6, "kubebuild": 6, "v2": 6, "docker": [6, 9, 11, 27, 34], "github": [6, 9, 12, 15, 27, 30], "dep": 6, "simpli": [6, 9, 11, 14, 22, 25], "sh": [6, 7, 10], "browser": 6, "navig": 6, "click": 6, "button": 6, "open": [6, 8, 9, 12, 13, 24], "consol": 6, "window": 6, "mkdir": 6, "p": [6, 9, 10, 14, 19, 24, 25, 34], "src": 6, "cd": [6, 7, 9, 10], "verifi": [6, 9, 19, 23], "v": [6, 30], "origin": [6, 19], "collabor": 6, "bug": [6, 24, 27, 31], "fix": [6, 24, 27, 29], "pr": 6, "makefil": 6, "img": 6, "push": 6, "wait": [6, 9, 11, 14, 19, 24, 25, 34], "built": [6, 8, 16, 17], "fetch": 6, "give": [6, 9, 10, 13, 27], "simpl": [6, 8, 9, 11, 13, 14, 22, 23, 25, 34], "descript": [6, 11], "word": [6, 19], "checkout": [6, 14, 34], "readi": [6, 9, 11, 13, 14, 16, 17, 22, 23, 25, 34], "keep": [6, 7, 10], "team": 6, "rebas": 6, "top": 6, "unnecessari": 6, "clean": 6, "whenev": 6, "never": [6, 34], "alwai": [6, 9, 22, 26, 30], "end": [6, 14, 15, 24, 27], "stash": 6, "save": [6, 9, 14, 16, 19, 25, 30, 34], "u": [6, 7, 9, 10, 11, 13, 14, 16, 17, 19, 22, 23, 24, 25, 26, 31], "veri": [6, 11, 14, 30, 34], "power": [6, 26], "understand": [6, 14, 31], "els": [6, 15], "risk": 6, "lose": [6, 20], "worth": 6, "nutshel": 6, "unwind": 6, "temporarili": 6, "re": [6, 14, 34], "prompt": 6, "continu": [6, 25], "close": [6, 11], "tell": 6, "done": [6, 7, 9, 10, 13, 24, 30], "test": [6, 13, 15, 27, 33], "again": [6, 14, 15, 22], "prepar": [6, 18, 19], "minim": [6, 11], "maintain": [6, 27], "commonli": 6, "squash": 6, "although": [6, 11, 14, 15, 16, 17, 19], "sometim": [6, 9, 30], "inspect": 6, "edit": [6, 7, 9, 10, 13], "even": [6, 25], "reorder": 6, "head": 6, "pleas": [6, 11, 26, 30, 33, 34], "line": [6, 16, 17, 19], "summari": 6, "prefix": 6, "relev": 6, "colon": 6, "changelog": 6, "good": [6, 8, 11], "sai": 6, "enter": [6, 11, 23, 25], "blank": 6, "carri": [6, 19], "rememb": [6, 9], "why": 6, "show": [6, 9, 25, 27], "better": [6, 10], "less": [6, 14, 15, 34], "compar": [6, 14], "imagin": 6, "yourself": 6, "month": 6, "ve": 6, "forgotten": 6, "did": 6, "speed": 6, "quickli": 6, "issu": [6, 12, 13, 14, 25, 28, 30, 32, 34], "1234": 6, "subject": [6, 26], "short": [6, 14], "sidecar": [6, 9, 11, 14, 34], "reconcil": [6, 15], "loop": 6, "And": [6, 11], "apropri": 6, "obviou": 6, "tab": 6, "focus": [7, 10], "improv": 7, "trick": 7, "tier": 7, "sdd": [7, 10], "raid0": [7, 10], "tri": [7, 10], "step": [7, 9, 10, 11, 13, 14, 15, 16, 17, 19, 24, 30, 34], "accord": [7, 9, 10, 14, 16, 25], "prefer": [7, 10, 16, 17], "eks_region": 7, "east": [7, 9, 11, 13, 14, 16, 19, 23, 24, 25, 26], "eks_zon": 7, "1a": [7, 9, 13, 14, 16, 19, 23, 24, 25, 26], "1b": [7, 11, 16, 19], "1c": [7, 16, 19], "folder": [7, 10, 30], "z": [7, 10, 27, 30], "r": 7, "benchmark": [7, 10], "stress": [7, 10], "cluster_nam": [7, 9, 10], "demo": [7, 10, 23], "ll": [7, 10, 24, 30], "nodegroup": [7, 16], "i3": 7, "2xlarg": 7, "toler": [7, 19], "instancetyp": 7, "desiredcapac": 7, "type": [7, 10, 11, 14, 15, 16, 17, 19, 23, 24, 25, 26, 27], "role": [7, 9, 10, 14, 19], "ssh": [7, 13, 29], "kubeletextraconfig": 7, "cpumanagerpolici": [7, 10], "c4": 7, "later": [7, 10], "larg": [7, 30], "stack": [7, 10, 12, 15], "sever": [7, 8, 16, 17, 33], "eksctl": [7, 16], "userguid": 7, "html": 7, "kubectl": [7, 9, 10, 11, 13, 14, 15, 16, 17, 19, 22, 23, 24, 25, 26, 30], "except": [7, 10], "nvme": [7, 10], "cloud": [7, 8, 9, 10, 13, 15, 17, 19], "usual": [7, 8, 10, 15, 27], "come": [7, 9, 10, 13, 26], "form": [7, 10, 30], "raid": [7, 10], "section": [7, 8, 9, 10, 16, 17, 30, 31], "care": [7, 8, 10], "abov": [7, 9, 10, 11, 13, 15, 16, 17, 34], "side": [7, 10, 15, 19, 34], "afterward": [7, 10], "capabl": [7, 8, 9, 10, 19], "earlier": [7, 10, 16, 19], "common": [7, 9, 10, 11, 14, 26, 30, 33, 34], "storageclass_xf": [7, 10], "launch": [7, 10], "highli": [7, 9, 10], "instruct": [7, 9, 10, 11, 14, 16], "found": [7, 9, 10], "experi": [7, 10], "explain": [8, 15, 16, 17, 26], "variou": [8, 9], "independ": [8, 19, 33], "2023": [8, 27], "enterpris": [8, 12, 13, 27], "exposeopt": [8, 15, 19], "spec": [8, 9, 11, 13, 14, 15, 19, 24, 25, 26, 34], "nodeservic": [8, 19], "broadcastopt": [8, 19], "cover": [8, 26], "addition": [8, 19], "annot": [8, 15], "incorpor": 8, "further": 8, "tweak": [8, 9], "Such": 8, "doesn": [8, 9, 10, 33, 34], "resolv": [8, 13, 25], "specif": [8, 9, 11, 16, 17, 19, 26, 33, 34], "routabl": 8, "traffic": [8, 16, 17, 33], "On": [8, 26, 29], "balanc": [8, 22], "public": 8, "via": [8, 9, 11], "ek": [8, 12, 18, 19], "scheme": [8, 34], "protocol": [8, 16], "gke": [8, 9, 12, 18, 19, 23], "regard": [8, 14, 17, 19], "learn": [8, 16, 31], "superset": 8, "alloc": [8, 11, 17], "help": [8, 9, 12, 30, 31], "cost": 8, "reliabl": 8, "latenc": 8, "secur": [8, 9], "metric": [8, 9, 11], "statu": [8, 9, 11, 12, 13, 14, 15, 16, 19, 23, 24, 25, 34], "assign": [8, 26], "ingress": [8, 17, 33], "ipaddress": 8, "scenario": 8, "definit": [8, 9, 10, 11, 13, 14, 25, 34], "deploi": [8, 12, 14, 34], "talk": [8, 13, 26, 30], "outsid": [8, 15], "assum": [8, 15, 19, 30], "subnet": [8, 16], "distinct": [8, 16, 17, 19], "interconnect": [8, 16, 17, 18], "facilit": 8, "assumpt": 8, "establish": [8, 9, 16, 17, 34], "page": [8, 17, 34], "know": 8, "reach": [8, 13, 15, 25, 33], "sinc": [8, 19], "suffici": 8, "lb": 8, "discov": [8, 19], "resid": [8, 17], "rout": [8, 15], "consequ": 8, "complex": 8, "ideal": 9, "best": 9, "fast": 9, "helm": [9, 12, 15, 27], "stabl": [9, 11, 34], "daunt": 9, "prone": 9, "fortun": 9, "life": [9, 23], "easier": [9, 14, 15, 34], "minikub": [9, 11], "breez": 9, "littl": 9, "Then": [9, 10, 11, 16, 17, 25], "awar": 9, "eval": 9, "manifest": [9, 19, 34], "upsteam": [9, 11], "condit": [9, 11, 14, 15, 19, 24, 26, 34], "issuer": 9, "deploy": [9, 11, 13, 15, 17, 18, 19, 24, 25, 34], "app": [9, 11, 15, 19, 24, 25, 34], "webhook": [9, 32, 34], "feel": [9, 30], "free": [9, 10, 30], "brows": 9, "our": [9, 14, 19, 26, 27, 30, 31, 34], "successfulli": [9, 15], "extend": [9, 33], "citizen": 9, "nativ": [9, 17], "easi": 9, "someth": [9, 13, 22, 30], "restart": [9, 11, 13, 14, 19, 23, 24, 25, 34], "ag": [9, 11, 13, 14, 23, 34], "9m49": 9, "7m43": 9, "6m46": 9, "datacenter_nam": 9, "rack_nam": 9, "instance_numb": 9, "pick": [9, 19], "resembl": [9, 17], "inconsequenti": 9, "anyth": 9, "l": [9, 11, 13, 14, 15, 24, 30], "squeez": 9, "emploi": 9, "event": 9, "asynchron": 9, "process": [9, 10, 16, 17, 19, 22, 25, 26, 34], "linux": 9, "2097152": [9, 19], "instead": [9, 33], "8000": 9, "only_rmw_uses_lwt": 9, "whichev": 9, "forbid_rmw": 9, "cql": [9, 13, 24], "pure": 9, "cqlsh": 9, "shell": [9, 14], "python": [9, 26], "svc": [9, 13, 14, 15, 22, 23], "plain": 9, "configmap": 9, "rack": [9, 11, 12, 13, 19, 23, 24, 25, 26], "statefulset": [9, 11, 14, 15, 25, 34], "tmp": 9, "o": [9, 14, 15, 27, 30], "dry": 9, "prefer_loc": 9, "dc_suffix": 9, "system_auth": [9, 13], "kept": 9, "deni": [9, 17], "product": [9, 13, 14, 15, 19], "networktopologystrategi": 9, "alter": 9, "WITH": 9, "replication_factor": 9, "main": [9, 11, 13, 19], "interact": [9, 22], "backup": [9, 12, 13, 21, 34], "decod": 9, "prometheu": [9, 11, 12, 13], "grafana": [9, 12], "introduc": [9, 15, 19, 26], "passwordauthent": 9, "usernam": [9, 15], "password": [9, 13, 15], "new_replication_factor": 9, "recommend": [9, 15, 19, 34], "mini": 9, "cli": [9, 11, 13, 17], "against": [9, 16, 17], "count": [9, 10, 13], "50": 9, "000": 9, "throttl": [9, 26], "throughput": 9, "30": 9, "sec": 9, "300": 9, "hack": 9, "cass": 9, "gen": 9, "py": 9, "num": [9, 10, 13, 17], "20g": 9, "50000000": 9, "limit": [9, 11, 13, 19, 24, 26], "30000": 9, "proper": 9, "argument": [9, 13, 30], "num_job": 9, "scylla_vers": 9, "thread": 9, "connections_per_host": 9, "print": [9, 25], "stdout": 9, "nodeselector": [9, 26], "exit": 9, "gb": 9, "ie": 9, "2g": 9, "10000000": 9, "eg": 9, "walk": [9, 16, 17, 19], "destroi": [9, 13, 19], "examin": [9, 13], "ok": 9, "gcp_user": 10, "gcloud": [10, 17], "gcp_project": 10, "project": [10, 12], "gcp_zone": 10, "west1": [10, 17], "yanniszark": 10, "arrikto": 10, "226716": 10, "region": [10, 16, 17, 19], "gcp_region": 10, "cluster_vers": 10, "validmastervers": 10, "systemconfig": 10, "kubeletconfig": 10, "nodepool": 10, "n1": [10, 17], "ssd": [10, 17], "20": [10, 13, 17, 27], "ubuntu_containerd": [10, 17], "stackdriv": 10, "autoupgrad": [10, 17], "autorepair": [10, 17], "32": 10, "raw": [10, 30], "upgrad": [10, 11, 12, 14, 21, 27], "repair": [10, 12, 13, 23, 24], "hard": 10, "timeout": [10, 11, 13, 14, 15], "pdb": 10, "At": [10, 14, 25], "rbac": 10, "clusterrolebind": [10, 30], "easiest": 10, "gcp": [10, 17], "iam": 10, "clusterrol": [10, 14, 30], "sed": [10, 14, 34], "inject": 10, "compon": [11, 13, 15], "could": 11, "16": [11, 13, 16, 17, 19, 27], "googleapi": [11, 34], "autogener": 11, "60": [11, 13], "search": 11, "hardwar": 11, "rewrit": 11, "autom": [11, 12, 13, 19, 34], "databas": [11, 13], "ma": 11, "interest": 11, "customiz": 11, "download": [11, 24], "hub": 11, "pullpolici": 11, "fullfil": 11, "compos": [11, 19], "follw": 11, "ifnotpres": 11, "much": [11, 23], "100m": [11, 19], "128mi": 11, "32mi": 11, "decid": [11, 27], "createselfsignedcertif": 11, "certificatesecretnam": 11, "overwrit": 11, "cours": 11, "scyllaimag": 11, "agentimag": 11, "5g": 11, "1gi": [11, 15, 24], "customzi": 11, "500m": 11, "500mi": 11, "controllerimag": 11, "controllerresourc": 11, "30mi": 11, "20mi": 11, "land": [11, 26], "bootstrap": [11, 23], "correctli": 11, "5dbcb54f5c": 11, "vjm4m": 11, "51": [11, 23], "wfjbw": 11, "clusterip": [11, 14, 23], "105": 11, "207": 11, "130": 11, "443": [11, 15], "TO": 11, "replicaset": 11, "669db64dd": 11, "bcm4v": 11, "89": 11, "844ccc56c4": 11, "drbth": 11, "rhwqx": 11, "231": [11, 23], "53": [11, 13], "5090": 11, "9180": [11, 14, 23], "5m58": 11, "4m29": 11, "5m59": 11, "43": [11, 14, 23], "149": 11, "92": 11, "7000": [11, 14, 23], "7001": [11, 14, 23], "7199": [11, 14, 23], "10001": [11, 14, 23], "9042": [11, 14, 23], "9142": [11, 14, 23], "9160": [11, 14, 23], "49": 11, "exactli": [11, 27], "ask": 11, "spin": [11, 13], "servicemonitor": 11, "notic": [11, 15], "prometh": 11, "abl": [11, 16, 33], "uninstal": 11, "downscal": 12, "report": [12, 31], "lesson": 12, "univers": 12, "multi": [12, 16, 17, 30], "scale": [12, 25, 30], "dead": 12, "autoh": 12, "topic": 12, "begin": [12, 25], "chart": [12, 15, 27, 34], "releas": [12, 34], "contribut": 12, "predict": 13, "With": [13, 17], "proprietari": 13, "softwar": 13, "licens": 13, "agreement": [13, 25], "spawn": 13, "mission": 13, "watch": 13, "synchron": 13, "fulli": [13, 19], "unschedul": [13, 20], "bare": [13, 15], "metal": [13, 15], "prod": 13, "37m": 13, "28m": 13, "7bd9f968b9": 13, "w25jw": 13, "2020": [13, 25, 27], "09": [13, 24, 27], "23t11": 13, "25": [13, 14, 19, 27], "27": [13, 19, 27], "882z": 13, "build_dat": 13, "built_bi": 13, "go_vers": 13, "loglevel": 13, "debug": [13, 30], "apiaddress": 13, "127": 13, "5080": 13, "_trace_id": 13, "lqejv3kdr5gx9m3xq2ynnq": 13, "28": 13, "435z": 13, "26": 13, "238z": 13, "20200816": 13, "76cc4dcc": 13, "pid": 13, "xqhkj0our8e6imdepm62hg": 13, "54": 13, "519z": 13, "tlscertfil": 13, "lib": 13, "scylla_manag": 13, "crt": [13, 15], "tlskeyfil": 13, "tlscafil": 13, "56090": 13, "prometheusscrapeinterv": 13, "5000000000": 13, "56112": 13, "logger": 13, "stderr": 13, "localdc": 13, "migratedir": 13, "migratetimeout": 13, "30000000000": 13, "migratemaxwaitschemaagr": 13, "300000000000": 13, "replicationfactor": 13, "600000000": 13, "tokenawar": 13, "certfil": 13, "usercertfil": 13, "userkeyfil": 13, "healthcheck": 13, "250000000": 13, "ssltimeout": 13, "750000000": 13, "diskspacefreeminperc": 13, "agemax": 13, "43200000000000": 13, "segmentsperrepair": 13, "shardparallelmax": 13, "shardfailedsegmentsmax": 13, "200000000": 13, "errorbackoff": 13, "shardingignoremsbbit": 13, "config_fil": 13, "mnt": 13, "tutori": 13, "d1d532cd": 13, "49f2": 13, "4c97": 13, "9263": 13, "25126532803b": 13, "sctool": [13, 24], "next": [13, 25], "400b2723": 13, "eec5": 13, "422a": 13, "b7f3": 13, "236a0e10575b": 13, "23": [13, 14], "sep": 13, "14": 13, "42": 13, "cest": 13, "15": [13, 24], "healthcheck_rest": 13, "28169610": 13, "a969": 13, "4c20": 13, "9d11": 13, "ab7568b8a1bd": 13, "29": 13, "57": 13, "1m": 13, "recur": 13, "healhcheck": 13, "frontend": 13, "altern": [13, 15], "prior": 13, "1d": 13, "weekli": 13, "7d": 13, "daili": 13, "7": [13, 19, 27], "spot": 13, "275aae7f": 13, "c436": 13, "4fc8": 13, "bcec": 13, "479e65fb8372": 13, "58": 13, "d4946360": 13, "c29d": 13, "4bb4": 13, "8b9d": 13, "619ada495c2a": 13, "38": 13, "shortli": 13, "utc": [13, 24], "69": 13, "06": [13, 27], "system_distribut": 13, "00": 13, "system_trac": 13, "wasn": 13, "lack": 13, "62": [13, 23], "107": [13, 19], "193": 13, "33": 13, "109": 13, "197": 13, "00000000": 13, "000000000000": 13, "adhoc": 13, "2b9dbe8c": 13, "9daa": 13, "4703": 13, "a66d": 13, "c29f63a917c8": 13, "infinit": 13, "appear": 13, "solv": [14, 34], "disambigu": [14, 34], "incompat": [14, 34], "involv": 14, "detach": 14, "garbag": 14, "shouldn": [14, 23], "caus": [14, 22, 23, 25, 26], "downtim": 14, "hacki": 14, "box": 14, "stage": [14, 25], "whole": [14, 25], "question": 14, "welcom": 14, "slack": 14, "sequenti": 14, "30m": [14, 34], "offici": 14, "websit": 14, "extract": [14, 19], "customresourcedefinit": [14, 34], "newli": 14, "metadata": [14, 15, 16, 19, 24, 26], "12a3678d": 14, "8511": 14, "4c9c": 14, "8a48": 14, "fa78d3992694": 14, "somewher": 14, "grant": 14, "verb": 14, "amend": 14, "109m": 14, "96": 14, "66": 14, "22": [14, 27], "108m": 14, "246": 14, "106m": 14, "ownerrefer": 14, "column": 14, "110m": 14, "107m": 14, "st": [14, 34], "104m": 14, "bound": [14, 20, 23, 26], "old": [14, 23, 34], "boot": [14, 25], "600": 14, "bump": 14, "endpointsselector": 15, "matchlabel": [15, 19], "volumeclaimtempl": 15, "webinterfac": 15, "passthrough": 15, "futur": [15, 16, 17], "skip": [15, 30], "5m": 15, "65b89d55bb": 15, "matter": 15, "packet": [15, 26], "tl": [15, 24], "sni": 15, "caller": 15, "properli": [15, 25, 33, 34], "grafana_serving_cert": 15, "index": [15, 19], "base64": [15, 19], "grafana_us": 15, "grafana_password": 15, "appropri": 15, "mydomain": 15, "cname": 15, "similar": [15, 16, 19, 30], "curl": 15, "w": 15, "http_code": 15, "cacert": 15, "echo": 15, "200": 15, "beyond": [15, 33], "ingress_port": 15, "loadbalanc": 15, "ingress_ip": 15, "conveni": 15, "internal_ip": 15, "external_ip": 15, "item": 15, "eq": 15, "internalip": 15, "easili": [16, 17], "tailor": [16, 17], "simplic": [16, 17, 19], "predefin": [16, 17, 30], "throughout": [16, 17, 19], "exemplari": [16, 17], "v1alpha5": 16, "clusterconfig": 16, "availabilityzon": 16, "cidr": [16, 17], "context": [16, 17, 26, 30], "return": [16, 17, 22], "workload": [16, 17, 26], "overlap": [16, 17], "ipv4": [16, 17], "2a": [16, 19], "2b": [16, 19], "2c": [16, 19], "172": [16, 17, 19, 23], "analog": [16, 17], "pcx": 16, "08077dcc008fbbab6": 16, "privat": 16, "destin": 16, "send": [16, 30], "preconfigur": 16, "publicroutet": 16, "flow": 16, "inbound": 16, "clustersharednodesecuritygroup": 16, "td05v9evu3b8": 16, "1fr9ydlu0ve7m": 16, "guidanc": [16, 17], "googl": 17, "virtual": 17, "secondari": 17, "east1": [17, 22], "17": [17, 27], "18": [17, 19, 27], "alia": 17, "subnetwork": 17, "permit": 17, "prioriti": 17, "f17db261": 17, "1000": 17, "udp": 17, "icmp": 17, "esp": 17, "ah": 17, "sctp": 17, "0bb60902": 17, "build": [18, 19, 27], "discuss": 19, "11": [19, 24, 27], "machineri": 19, "scyladb": 19, "intervent": 19, "notabl": 19, "behind": 19, "mechan": 19, "understood": 19, "contact": 19, "join": [19, 23], "enhanc": 19, "propos": 19, "scyllaclus": 19, "headless": 19, "howev": [19, 26], "context_dc1": 19, "context_dc2": 19, "correspondingli": 19, "accordingli": 19, "center": 19, "1800g": 19, "agentresourc": [19, 26], "250m": 19, "56g": 19, "placement": [19, 26], "podantiaffin": 19, "requiredduringschedulingignoredduringexecut": 19, "labelselector": 19, "nodeaffin": 19, "nodeselectorterm": 19, "matchexpress": 19, "un": [19, 23], "nodetool": [19, 23], "move": [19, 23, 25, 26], "70": 19, "195": 19, "290": 19, "kb": [19, 23], "256": [19, 23], "494277b9": 19, "121c": 19, "4af9": 19, "bd63": 19, "3d0a7b9305f7": 19, "59": 19, "559": 19, "a3a98e08": 19, "0dfd": 19, "4a25": 19, "a96a": 19, "c5ab2f47eb37": 19, "19": [19, 27], "237": 19, "64b6292a": 19, "327f": 19, "4128": 19, "852a": 19, "6004039f402e": 19, "ephemer": 19, "natur": 19, "ill": 19, "advis": [19, 30, 33], "high": 19, "likelihood": 19, "undesir": 19, "fallback": 19, "peer": 19, "unreach": 19, "sheer": 19, "dc2": 19, "705": 19, "764": 19, "634": 19, "39": 19, "209": 19, "336": 19, "7c30ea55": 19, "7a4f": 19, "4d93": 19, "86f7": 19, "c881772ebe62": 19, "759": 19, "665dde7e": 19, "e420": 19, "4db3": 19, "8c54": 19, "ca71efd39b2": 19, "87": 19, "503": 19, "c19c89cb": 19, "e24c": 19, "4062": 19, "9df4": 19, "2aa90ab29a99": 19, "cr": 19, "random": 19, "auth": 19, "auth_token": 19, "84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf": 19, "stringdata": 19, "sync": [19, 23], "incid": 20, "explicit": 20, "becom": [20, 25, 27], "hi": 20, "lost": 21, "mainten": [21, 25], "probe": [22, 34], "stai": 22, "aliv": 22, "bring": [22, 23, 25, 34], "front": 22, "stream": 23, "bandwidth": 23, "125": 23, "110": 23, "74": 23, "63": 23, "8ebd6114": 23, "969c": 23, "44af": 23, "a978": 23, "87a4a6c65c3": 23, "189": 23, "91": 23, "03": [23, 27], "35d0cb19": 23, "35ef": 23, "482b": 23, "92a4": 23, "b63eee4527e5": 23, "77": 23, "1ffa7a82": 23, "c41c": 23, "4706": 23, "8f5f": 23, "4d45a39c7003": 23, "3h12m": 23, "3h11m": 23, "3h5m": 23, "drain": [23, 25], "b4b390a1": 23, "6j12": 23, "daemonset": [23, 26], "3h21m": 23, "3h19m": 23, "8m14": 23, "recreat": [23, 34], "3h27m": 23, "3h25m": 23, "visibl": 23, "191": 23, "fresh": [24, 34], "automatictlscertif": 24, "arg": 24, "af1dd5cd": 24, "0406": 24, "4974": 24, "949f": 24, "dc9842980080": 24, "ebd82268": 24, "efb7": 24, "407e": 24, "a540": 24, "3619ae053778": 24, "cluster_id": 24, "backup_loc": 24, "ff36d7e0": 24, "af2": 24, "458c": 24, "afe6": 24, "868e0f3396b2": 24, "sm_20240105115931utc": 24, "409mib": 24, "system_schema": [24, 25], "snapshot_tag": 24, "57228c52": 24, "7cf6": 24, "4271": 24, "8c8d": 24, "d446ff160747": 24, "0dd20cdf": 24, "abc4": 24, "11ee": 24, "951c": 24, "6e7993cf42": 24, "05": [24, 27], "jan": 24, "02": 24, "success": 24, "214": 24, "150k": 24, "suggest": 24, "63642069": 24, "bed5": 24, "4def": 24, "ba0f": 24, "68c49e47ace1": 24, "ab015cef": 24, "abc8": 24, "9521": 24, "48": 24, "04": [24, 27], "post": 24, "detect": 25, "nightli": 25, "so_data_20201228135002utc": 25, "validate_upgrad": 25, "so_system_20201228135002utc": 25, "ondelet": 25, "upgradestrategi": 25, "trace": 25, "displai": 25, "begin_upgrad": 25, "check_schema_agr": 25, "create_system_backup": 25, "find_next_rack": 25, "decis": 25, "upgrade_image_in_pod_spec": 25, "find_next_nod": 25, "enable_maintenance_mod": 25, "drain_nod": 25, "backup_data": 25, "disable_maintenance_mod": 25, "delete_pod": 25, "clear_data_backup": 25, "clear_system_backup": 25, "restore_upgrade_strategi": 25, "finish_upgrad": 25, "recov": 25, "stuck": 25, "refus": 25, "sstabl": 25, "left": 25, "suppos": 26, "perftun": 26, "optmiz": 26, "kernel": 26, "spread": 26, "irq": 26, "effic": 26, "interrupt": 26, "One": 26, "switch": 26, "coupl": 26, "daemon": 26, "space": 26, "advantag": 26, "special": 26, "qo": 26, "doubl": 26, "cf": 26, "quota": 26, "enforc": 26, "distribut": 26, "fulfil": 26, "receiv": 26, "500gi": 26, "1g": 26, "16g": 26, "aim": 27, "ship": 27, "approxim": 27, "week": 27, "advisori": 27, "hit": [27, 30], "code": [27, 34], "freez": 27, "2024": 27, "01": 27, "08": 27, "everyon": 27, "07": 27, "2022": 27, "2021": 27, "21": 27, "elig": 27, "situat": 27, "assess": 27, "action": 27, "branch": [27, 34], "trigger": 27, "artifact": 27, "e2": 27, "suit": [27, 33], "vx": 27, "y": 27, "rc": 27, "ga": 27, "scratch": [27, 34], "candid": 27, "qualiti": 27, "qa": 27, "sing": 27, "sha": 27, "Be": 27, "cri": 27, "v1alpha2": 27, "troubleshoot": 28, "gather": 28, "8th": 29, "migrat": [29, 34], "008_": 29, "hairpin": 29, "sudo": 29, "docker0": 29, "promisc": 29, "goe": 30, "wrong": 30, "censor": 30, "That": 30, "said": 30, "review": 30, "archiv": [30, 31], "kubeconfig": 30, "kube": 30, "slight": 30, "deviat": 30, "runtim": 30, "selinux": 30, "mention": 30, "lsetxattr": 30, "view": 30, "minifi": 30, "user_nam": 30, "few": 30, "serviceaccount": 30, "must_gather_token": 30, "1h": 30, "mktemp": [30, 34], "yq": 30, "mikefarah": 30, "rm": 30, "ro": 30, "pwd": 30, "workspac": 30, "workdir": 30, "namespace_with_broken_scyllaclust": 30, "wouldn": 30, "administr": 31, "paid": 31, "aris": 31, "visit": 31, "unfortun": 33, "plane": [33, 34], "firewal": 33, "conform": 33, "break": 33, "workaround": 33, "reconfigur": 33, "5871": 34, "7735": 34, "release_nam": 34, "tmpdir": 34, "untar": 34, "untardir": 34, "printf": 34, "xarg": 34, "minor": 34, "brought": 34, "lot": 34, "mutatingwebhookconfigur": 34, "validatingwebhookconfigur": 34, "95m": 34, "livenessprob": 34, "httpget": 34, "healthz": 34, "8080": 34, "readinessprob": 34, "retainkei": 34, "readyz": 34, "cat": 34}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"scylla": [0, 1, 2, 3, 4, 6, 7, 9, 10, 11, 12, 13, 19, 21, 23, 25, 29, 34], "scylladb": [0, 1, 2, 3, 4, 7, 10, 16, 17, 18, 19], "com": [0, 1, 2, 3, 4], "nodeconfig": 1, "v1alpha1": [1, 3, 4], "descript": [1, 2, 3, 4], "specif": [1, 2, 3, 4], "metadata": [1, 2, 3, 4], "type": [1, 2, 3, 4, 8], "spec": [1, 2, 3, 4], "localdisksetup": 1, "filesystem": 1, "mount": 1, "raid": 1, "raid0": 1, "devic": 1, "placement": [1, 2, 3], "affin": 1, "nodeaffin": [1, 2, 3], "preferredduringschedulingignoredduringexecut": [1, 2, 3], "prefer": [1, 2, 3], "matchexpress": [1, 2, 3], "matchfield": [1, 2, 3], "requiredduringschedulingignoredduringexecut": [1, 2, 3], "nodeselectorterm": [1, 2, 3], "podaffin": [1, 2, 3], "podaffinityterm": [1, 2, 3], "labelselector": [1, 2, 3], "matchlabel": [1, 2, 3], "namespaceselector": [1, 2, 3], "podantiaffin": [1, 2, 3], "nodeselector": 1, "toler": [1, 2, 3], "statu": [1, 2, 3, 4], "condit": [1, 2, 3], "nodestatus": 1, "scyllaclust": [2, 8, 9], "v1": [2, 14, 34], "altern": [2, 9], "backup": [2, 24], "datacent": [2, 18, 19], "rack": 2, "agentresourc": 2, "claim": [2, 3], "limit": [2, 3, 30], "request": [2, 3, 6], "agentvolumemount": 2, "resourc": [2, 3, 11, 30], "storag": [2, 3], "volumemount": 2, "volum": [2, 7, 10], "awselasticblockstor": 2, "azuredisk": 2, "azurefil": 2, "cephf": 2, "secretref": 2, "cinder": 2, "configmap": 2, "item": 2, "csi": 2, "nodepublishsecretref": 2, "volumeattribut": 2, "downwardapi": 2, "fieldref": 2, "resourcefieldref": 2, "emptydir": 2, "ephemer": 2, "volumeclaimtempl": [2, 3], "datasourc": [2, 3], "datasourceref": [2, 3], "selector": [2, 3], "fc": 2, "flexvolum": 2, "option": [2, 8], "flocker": 2, "gcepersistentdisk": 2, "gitrepo": 2, "glusterf": 2, "hostpath": 2, "iscsi": 2, "nf": 2, "persistentvolumeclaim": 2, "photonpersistentdisk": 2, "portworxvolum": 2, "project": [2, 6], "sourc": 2, "clustertrustbundl": 2, "secret": 2, "serviceaccounttoken": 2, "quobyt": 2, "rbd": 2, "scaleio": 2, "storageo": 2, "vspherevolum": 2, "exposeopt": [2, 3], "broadcastopt": 2, "client": [2, 8], "podip": [2, 8, 19], "node": [2, 7, 8, 10, 16, 17, 19, 20, 21, 23, 26], "cql": 2, "ingress": [2, 3, 15], "annot": [2, 3], "nodeservic": 2, "genericupgrad": 2, "imagepullsecret": 2, "network": [2, 9, 16, 17, 19], "repair": 2, "upgrad": [2, 25, 34], "scylladbmonitor": [3, 15, 19], "compon": 3, "grafana": [3, 15], "authent": 3, "webinterfac": 3, "prometheu": [3, 15], "label": 3, "endpointsselector": 3, "scyllaoperatorconfig": 4, "api": 5, "refer": 5, "group": [5, 16], "kind": 5, "contribut": 6, "oper": [6, 7, 9, 10, 11, 12, 15, 16, 17, 21, 34], "prerequisit": [6, 7, 9, 10, 11, 13, 15, 16, 17, 19, 30], "initi": [6, 9], "setup": [6, 7, 10], "creat": [6, 7, 9, 10, 16, 17], "fork": 6, "clone": 6, "your": [6, 31], "add": 6, "upstream": 6, "remot": 6, "develop": 6, "build": [6, 16, 17], "branch": 6, "updat": [6, 16], "submit": 6, "pull": 6, "commit": 6, "histori": 6, "messag": 6, "deploi": [7, 9, 10, 11, 13, 15, 16, 17, 18, 19], "ek": [7, 16, 33], "tl": [7, 10, 11], "dr": [7, 10, 11], "walkthrough": [7, 10], "configur": [7, 9, 10, 16, 17], "environ": [7, 10], "variabl": [7, 10], "an": [7, 15], "cluster": [7, 8, 9, 10, 13, 16, 17, 18, 19, 30, 31, 33], "instal": [7, 11, 33], "script": 7, "third": 7, "parti": 7, "depend": 7, "set": [7, 9, 10], "up": [7, 9, 10, 13, 29], "local": [7, 9, 10], "provision": [7, 10], "access": [7, 9, 10, 15], "databas": [7, 9, 10], "delet": [7, 10], "expos": 8, "servic": 8, "templat": 8, "headless": 8, "clusterip": 8, "loadbalanc": 8, "broadcast": 8, "serviceclusterip": 8, "serviceloadbalanceringress": 8, "deploy": 8, "exampl": 8, "In": 8, "onli": 8, "vpc": [8, 16, 17], "multi": [8, 18, 19], "internet": 8, "kubernet": [9, 10, 13, 16, 17, 18, 19, 26], "run": [9, 16, 17, 30], "download": 9, "cert": [9, 11], "manag": [9, 11, 13, 15, 19, 29], "host": 9, "contain": 9, "kernel": 9, "paramet": 9, "agent": 9, "auth": 9, "token": 9, "monitor": [9, 11, 15], "scale": 9, "benchmark": 9, "cassandra": 9, "stress": 9, "clean": [9, 13], "troubleshoot": [9, 13, 31, 32, 33], "gke": [10, 17, 33], "googl": 10, "engin": 10, "yourself": 10, "admin": 10, "stack": 11, "us": [11, 15, 19, 21], "helm": [11, 34], "chart": 11, "repositori": 11, "imag": 11, "webhook": [11, 33], "custom": [11, 33], "control": 11, "result": 11, "cleanup": [11, 20], "document": 12, "architectur": 13, "registr": 13, "task": 13, "schedul": [13, 27], "version": [14, 25], "migrat": 14, "v0": [14, 34], "3": [14, 34], "0": [14, 34], "procedur": 14, "requir": 15, "wait": 15, "roll": 15, "out": 15, "haproxi": 15, "connect": 15, "through": 15, "resolv": 15, "domain": 15, "unresolv": 15, "variant": 15, "externalip": 15, "nodeport": 15, "multipl": [16, 17, 19], "amazon": 16, "inter": [16, 17], "first": [16, 17, 19], "prepar": [16, 17], "second": [16, 17, 19], "peer": 16, "rout": 16, "tabl": 16, "secur": 16, "subnet": 17, "firewal": 17, "rule": 17, "interconnect": 19, "extern": 19, "seed": 19, "context": 19, "retriev": 19, "automat": 20, "replac": [20, 23], "case": 20, "when": 20, "k8": 20, "i": 20, "lost": 20, "mainten": 22, "mode": 22, "dead": 23, "restor": 24, "from": 24, "perform": 26, "tune": 26, "releas": 27, "support": [27, 28, 31], "backport": 27, "polici": 27, "ci": 27, "cd": 27, "autom": 27, "promot": 27, "gener": 27, "avail": 27, "matrix": 27, "known": 29, "issu": [29, 31, 33], "doe": 29, "boot": 29, "minikub": 29, "truncat": 29, "queri": 29, "work": 29, "gather": [30, 31], "data": [30, 31], "must": 30, "podman": 30, "docker": 30, "particular": 30, "namespac": 30, "collect": 30, "everi": 30, "overview": 31, "get": 31, "about": 31, "cni": 33, "privat": 33, "via": 34, "kubectl": 34, "2": 34, "1": 34}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.todo": 2, "sphinx": 60}, "alltitles": {"Build multiple Amazon EKS clusters with inter-Kubernetes networking": [[16, "build-multiple-amazon-eks-clusters-with-inter-kubernetes-networking"]], "Prerequisites": [[16, "prerequisites"], [17, "prerequisites"], [19, "prerequisites"], [30, "prerequisites"], [15, "prerequisites"], [13, "prerequisites"], [10, "prerequisites"], [9, "prerequisites"], [11, "prerequisites"], [6, "prerequisites"], [7, "prerequisites"]], "Create EKS clusters": [[16, "create-eks-clusters"]], "Create the first EKS cluster": [[16, "create-the-first-eks-cluster"]], "Deploy ScyllaDB Operator": [[16, "deploy-scylladb-operator"], [17, "deploy-scylladb-operator"]], "Prepare nodes for running ScyllaDB": [[16, "prepare-nodes-for-running-scylladb"], [17, "prepare-nodes-for-running-scylladb"]], "Create the second EKS cluster": [[16, "create-the-second-eks-cluster"]], "Configure the network": [[16, "configure-the-network"]], "Create VPC peering": [[16, "create-vpc-peering"]], "Update route tables": [[16, "update-route-tables"]], "Update security groups": [[16, "update-security-groups"]], "Maintenance mode": [[22, "maintenance-mode"]], "Replacing a Scylla node": [[23, "replacing-a-scylla-node"]], "Replacing a dead node": [[23, "replacing-a-dead-node"]], "Automatic cleanup and replacement in case when k8s node is lost": [[20, "automatic-cleanup-and-replacement-in-case-when-k8s-node-is-lost"]], "Build multiple GKE clusters with inter-Kubernetes networking": [[17, "build-multiple-gke-clusters-with-inter-kubernetes-networking"]], "Create and configure a VPC network": [[17, "create-and-configure-a-vpc-network"]], "Create the VPC network": [[17, "create-the-vpc-network"]], "Create VPC network subnets": [[17, "create-vpc-network-subnets"]], "Create GKE clusters": [[17, "create-gke-clusters"]], "Create the first GKE cluster": [[17, "create-the-first-gke-cluster"]], "Create the second GKE cluster": [[17, "create-the-second-gke-cluster"]], "Configure the firewall rules": [[17, "configure-the-firewall-rules"]], "Node operations using Scylla Operator": [[21, "node-operations-using-scylla-operator"]], "Deploying multi-datacenter ScyllaDB clusters in Kubernetes": [[18, "deploying-multi-datacenter-scylladb-clusters-in-kubernetes"]], "Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters": [[19, "deploy-a-multi-datacenter-scylladb-cluster-in-multiple-interconnected-kubernetes-clusters"]], "Multi Datacenter ScyllaDB Cluster": [[19, "multi-datacenter-scylladb-cluster"]], "External seeds": [[19, "external-seeds"]], "Networking": [[19, "networking"]], "Deploy a multi-datacenter ScyllaDB Cluster": [[19, "deploy-a-multi-datacenter-scylladb-cluster"]], "Using context": [[19, "using-context"]], "Deploy the first datacenter": [[19, "deploy-the-first-datacenter"]], "Retrieve PodIPs of ScyllaDB nodes for use as external seeds": [[19, "retrieve-podips-of-scylladb-nodes-for-use-as-external-seeds"]], "Deploy the second datacenter": [[19, "deploy-the-second-datacenter"]], "Scylla Manager": [[19, "scylla-manager"], [11, "scylla-manager"]], "ScyllaDBMonitoring": [[19, "scylladbmonitoring"]], "Support": [[28, "support"]], "Known issues": [[29, "known-issues"]], "Scylla Manager does not boot up on Minikube": [[29, "scylla-manager-does-not-boot-up-on-minikube"]], "TRUNCATE queries does not work on Minikube": [[29, "truncate-queries-does-not-work-on-minikube"]], "Performance tuning": [[26, "performance-tuning"]], "Node tuning": [[26, "node-tuning"]], "Kubernetes tuning": [[26, "kubernetes-tuning"]], "Upgrading version of Scylla": [[25, "upgrading-version-of-scylla"]], "Releases": [[27, "releases"]], "Schedule": [[27, "schedule"]], "Supported releases": [[27, "supported-releases"]], "Backport policy": [[27, "backport-policy"]], "CI/CD": [[27, "ci-cd"]], "Automated promotions": [[27, "automated-promotions"]], "Generally available": [[27, "generally-available"]], "Support matrix": [[27, "support-matrix"]], "Support overview": [[31, "support-overview"]], "Get support": [[31, "get-support"]], "Troubleshooting issues": [[31, "troubleshooting-issues"]], "Gather data about your cluster": [[31, "gather-data-about-your-cluster"]], "Gathering data with must-gather": [[30, "gathering-data-with-must-gather"]], "Running must-gather": [[30, "running-must-gather"]], "Podman": [[30, "podman"]], "Docker": [[30, "docker"]], "Limiting must-gather to a particular namespace": [[30, "limiting-must-gather-to-a-particular-namespace"]], "Collecting every resource in the cluster": [[30, "collecting-every-resource-in-the-cluster"]], "Restore from backup": [[24, "restore-from-backup"]], "Troubleshooting": [[32, "troubleshooting"], [13, "troubleshooting"], [9, "troubleshooting"]], "Upgrade of Scylla Operator": [[34, "upgrade-of-scylla-operator"]], "Upgrade via Helm": [[34, "upgrade-via-helm"]], "Upgrade via kubectl": [[34, "upgrade-via-kubectl"]], "v1.2.0 -> v1.3.0": [[34, "v1-2-0-v1-3-0"]], "v1.1.0 -> v1.2.0": [[34, "v1-1-0-v1-2-0"]], "v1.0.0 -> v1.1.0": [[34, "v1-0-0-v1-1-0"]], "v0.3.0 -> v1.0.0": [[34, "v0-3-0-v1-0-0"]], "Troubleshooting installation issues": [[33, "troubleshooting-installation-issues"]], "Webhooks": [[33, "webhooks"]], "EKS": [[33, "eks"]], "Custom CNI": [[33, "custom-cni"]], "GKE": [[33, "gke"]], "Private clusters": [[33, "private-clusters"]], "Monitoring": [[15, "monitoring"], [11, "monitoring"]], "Deploy managed monitoring": [[15, "deploy-managed-monitoring"]], "Requirements": [[15, "requirements"]], "Deploy Prometheus Operator": [[15, "deploy-prometheus-operator"]], "Wait for Prometheus Operator to roll out": [[15, "wait-for-prometheus-operator-to-roll-out"]], "Deploy HAProxy Ingress": [[15, "deploy-haproxy-ingress"]], "Wait for HAProxy Ingress to roll out": [[15, "wait-for-haproxy-ingress-to-roll-out"]], "Deploy ScyllaDBMonitoring": [[15, "deploy-scylladbmonitoring"]], "Wait for ScyllaDBMonitoring to roll out": [[15, "wait-for-scylladbmonitoring-to-roll-out"]], "Wait for Prometheus to roll out": [[15, "wait-for-prometheus-to-roll-out"]], "Wait for Grafana to roll out": [[15, "wait-for-grafana-to-roll-out"]], "Accessing Grafana": [[15, "accessing-grafana"]], "Connecting through Ingress using a resolvable domain": [[15, "connecting-through-ingress-using-a-resolvable-domain"]], "Connecting through Ingress using an unresolvable domain": [[15, "connecting-through-ingress-using-an-unresolvable-domain"]], "Variants": [[15, "variants"]], "Ingress ExternalIP": [[15, "ingress-externalip"]], "Ingress NodePort": [[15, "ingress-nodeport"]], "Connection": [[15, "connection"]], "Deploying Scylla Manager on a Kubernetes Cluster": [[13, "deploying-scylla-manager-on-a-kubernetes-cluster"]], "Architecture": [[13, "architecture"]], "Deploy Scylla Manager": [[13, "deploy-scylla-manager"]], "Cluster registration": [[13, "cluster-registration"]], "Task scheduling": [[13, "task-scheduling"]], "Clean Up": [[13, "clean-up"], [9, "clean-up"]], "Scylla Operator Documentation": [[12, "scylla-operator-documentation"]], "Deploying Scylla on GKE": [[10, "deploying-scylla-on-gke"]], "TL;DR;": [[10, "tl-dr"], [7, "tl-dr"]], "Walkthrough": [[10, "walkthrough"], [7, "walkthrough"]], "Google Kubernetes Engine Setup": [[10, "google-kubernetes-engine-setup"]], "Configure environment variables": [[10, "configure-environment-variables"], [7, "configure-environment-variables"]], "Creating a GKE cluster": [[10, "creating-a-gke-cluster"]], "Setting Yourself as cluster-admin": [[10, "setting-yourself-as-cluster-admin"]], "Deploying ScyllaDB Operator": [[10, "deploying-scylladb-operator"], [7, "deploying-scylladb-operator"]], "Setting up nodes for ScyllaDB": [[10, "setting-up-nodes-for-scylladb"], [7, "setting-up-nodes-for-scylladb"]], "Deploying Local Volume Provisioner": [[10, "deploying-local-volume-provisioner"], [7, "deploying-local-volume-provisioner"]], "Deploy Scylla cluster": [[10, "deploy-scylla-cluster"]], "Deploying ScyllaDB": [[10, "deploying-scylladb"], [7, "deploying-scylladb"]], "Accessing the database": [[10, "accessing-the-database"], [7, "accessing-the-database"]], "Deleting a GKE cluster": [[10, "deleting-a-gke-cluster"]], "Version migrations": [[14, "version-migrations"]], "v0.3.0 -> v1.0.0 migration": [[14, "v0-3-0-v1-0-0-migration"]], "Procedure": [[14, "procedure"]], "Deploying Scylla on a Kubernetes Cluster": [[9, "deploying-scylla-on-a-kubernetes-cluster"]], "Running locally": [[9, "running-locally"]], "Download Scylla Operator": [[9, "download-scylla-operator"]], "Deploy Cert Manager": [[9, "deploy-cert-manager"], [11, "deploy-cert-manager"]], "Deploy Scylla Operator": [[9, "deploy-scylla-operator"]], "Create and Initialize a Scylla Cluster": [[9, "create-and-initialize-a-scylla-cluster"]], "Configure host networking": [[9, "configure-host-networking"]], "Configure container kernel parameters": [[9, "configure-container-kernel-parameters"]], "Deploying Alternator": [[9, "deploying-alternator"]], "Accessing the Database": [[9, "accessing-the-database"]], "Configure Scylla": [[9, "configure-scylla"]], "Configure Scylla Manager Agent": [[9, "configure-scylla-manager-agent"]], "Scylla Manager Agent auth token": [[9, "scylla-manager-agent-auth-token"]], "Set up monitoring": [[9, "set-up-monitoring"]], "Scale a ScyllaCluster": [[9, "scale-a-scyllacluster"]], "Benchmark with cassandra-stress": [[9, "benchmark-with-cassandra-stress"]], "Deploying Scylla stack using Helm Charts": [[11, "deploying-scylla-stack-using-helm-charts"]], "TL;DR": [[11, "tl-dr"]], "Helm Chart repository": [[11, "helm-chart-repository"]], "Scylla Operator Chart": [[11, "scylla-operator-chart"]], "image": [[11, "image"]], "resources": [[11, "resources"]], "webhook": [[11, "webhook"]], "Customization": [[11, "customization"], [11, "id1"], [11, "id3"]], "Installation": [[11, "installation"], [11, "id2"], [11, "id4"]], "Scylla Helm Chart": [[11, "scylla-helm-chart"]], "Scylla Manager Helm Chart": [[11, "scylla-manager-helm-chart"]], "Scylla Manager Controller": [[11, "scylla-manager-controller"]], "Scylla": [[11, "scylla"]], "Results": [[11, "results"]], "Cleanup": [[11, "cleanup"]], "Exposing ScyllaCluster": [[8, "exposing-scyllacluster"]], "Expose Options": [[8, "expose-options"]], "Node Service Template": [[8, "node-service-template"]], "Headless Type": [[8, "headless-type"]], "ClusterIP Type": [[8, "clusterip-type"]], "LoadBalancer Type": [[8, "loadbalancer-type"]], "Broadcast Options": [[8, "broadcast-options"]], "PodIP Type": [[8, "podip-type"]], "ServiceClusterIP Type": [[8, "serviceclusterip-type"]], "ServiceLoadBalancerIngress Type": [[8, "serviceloadbalanceringress-type"]], "Deployment Examples": [[8, "deployment-examples"]], "In-cluster only": [[8, "in-cluster-only"]], "In-cluster node-to-node, VPC clients-to-nodes": [[8, "in-cluster-node-to-node-vpc-clients-to-nodes"]], "Multi VPC": [[8, "multi-vpc"]], "Internet": [[8, "internet"]], "NodeConfig (scylla.scylladb.com/v1alpha1)": [[1, "nodeconfig-scylla-scylladb-com-v1alpha1"]], "Description": [[1, "description"], [1, "id1"], [1, "id2"], [1, "id4"], [1, "id6"], [1, "id8"], [1, "id10"], [1, "id12"], [1, "id14"], [1, "id16"], [1, "id18"], [1, "id20"], [1, "id22"], [1, "id24"], [1, "id26"], [1, "id28"], [1, "id30"], [1, "id32"], [1, "id34"], [1, "id36"], [1, "id38"], [1, "id40"], [1, "id42"], [1, "id44"], [1, "id46"], [1, "id48"], [1, "id50"], [1, "id52"], [1, "id54"], [1, "id56"], [1, "id58"], [1, "id60"], [1, "id62"], [1, "id64"], [1, "id66"], [1, "id68"], [1, "id70"], [1, "id72"], [1, "id74"], [1, "id76"], [1, "id78"], [1, "id80"], [1, "id82"], [1, "id84"], [1, "id86"], [1, "id88"], [1, "id90"], [1, "id92"], [1, "id94"], [1, "id96"], [1, "id98"], [1, "id100"], [1, "id102"], [1, "id104"], [1, "id106"], [1, "id108"], [1, "id110"], [2, "description"], [2, "id1"], [2, "id2"], [2, "id4"], [2, "id6"], [2, "id8"], [2, "id10"], [2, "id12"], [2, "id14"], [2, "id16"], [2, "id18"], [2, "id20"], [2, "id22"], [2, "id24"], [2, "id26"], [2, "id28"], [2, "id30"], [2, "id32"], [2, "id34"], [2, "id36"], [2, "id38"], [2, "id40"], [2, "id42"], [2, "id44"], [2, "id46"], [2, "id48"], [2, "id50"], [2, "id52"], [2, "id54"], [2, "id56"], [2, "id58"], [2, "id60"], [2, "id62"], [2, "id64"], [2, "id66"], [2, "id68"], [2, "id70"], [2, "id72"], [2, "id74"], [2, "id76"], [2, "id78"], [2, "id80"], [2, "id82"], [2, "id84"], [2, "id86"], [2, "id88"], [2, "id90"], [2, "id92"], [2, "id94"], [2, "id96"], [2, "id98"], [2, "id100"], [2, "id102"], [2, "id104"], [2, "id106"], [2, "id108"], [2, "id110"], [2, "id112"], [2, "id114"], [2, "id116"], [2, "id118"], [2, "id120"], [2, "id122"], [2, "id124"], [2, "id126"], [2, "id128"], [2, "id130"], [2, "id132"], [2, "id134"], [2, "id136"], [2, "id138"], [2, "id140"], [2, "id142"], [2, "id144"], [2, "id146"], [2, "id148"], [2, "id150"], [2, "id152"], [2, "id154"], [2, "id156"], [2, "id158"], [2, "id160"], [2, "id162"], [2, "id164"], [2, "id166"], [2, "id168"], [2, "id170"], [2, "id172"], [2, "id174"], [2, "id176"], [2, "id178"], [2, "id180"], [2, "id182"], [2, "id184"], [2, "id186"], [2, "id188"], [2, "id190"], [2, "id192"], [2, "id194"], [2, "id196"], [2, "id198"], [2, "id200"], [2, "id202"], [2, "id204"], [2, "id206"], [2, "id208"], [2, "id210"], [2, "id212"], [2, "id214"], [2, "id216"], [2, "id218"], [2, "id220"], [2, "id222"], [2, "id224"], [2, "id226"], [2, "id228"], [2, "id230"], [2, "id232"], [2, "id234"], [2, "id236"], [2, "id238"], [2, "id240"], [2, "id242"], [2, "id244"], [2, "id246"], [2, "id248"], [2, "id250"], [2, "id252"], [2, "id254"], [2, "id256"], [2, "id258"], [2, "id260"], [2, "id262"], [2, "id264"], [2, "id266"], [2, "id268"], [2, "id270"], [2, "id272"], [2, "id274"], [2, "id276"], [2, "id278"], [2, "id280"], [2, "id282"], [2, "id284"], [2, "id286"], [2, "id288"], [2, "id290"], [2, "id292"], [2, "id294"], [2, "id296"], [2, "id298"], [2, "id300"], [4, "description"], [4, "id1"], [4, "id2"], [4, "id4"], [3, "description"], [3, "id1"], [3, "id2"], [3, "id4"], [3, "id6"], [3, "id8"], [3, "id10"], [3, "id12"], [3, "id14"], [3, "id16"], [3, "id18"], [3, "id20"], [3, "id22"], [3, "id24"], [3, "id26"], [3, "id28"], [3, "id30"], [3, "id32"], [3, "id34"], [3, "id36"], [3, "id38"], [3, "id40"], [3, "id42"], [3, "id44"], [3, "id46"], [3, "id48"], [3, "id50"], [3, "id52"], [3, "id54"], [3, "id56"], [3, "id58"], [3, "id60"], [3, "id62"], [3, "id64"], [3, "id66"], [3, "id68"], [3, "id70"], [3, "id72"], [3, "id74"], [3, "id76"], [3, "id78"], [3, "id80"], [3, "id82"], [3, "id84"], [3, "id86"], [3, "id88"], [3, "id90"], [3, "id92"], [3, "id94"], [3, "id96"], [3, "id98"], [3, "id100"], [3, "id102"], [3, "id104"], [3, "id106"], [3, "id108"], [3, "id110"], [3, "id112"], [3, "id114"], [3, "id116"], [3, "id118"], [3, "id120"], [3, "id122"], [3, "id124"], [3, "id126"], [3, "id128"], [3, "id130"], [3, "id132"], [3, "id134"], [3, "id136"], [3, "id138"], [3, "id140"], [3, "id142"], [3, "id144"], [3, "id146"], [3, "id148"], [3, "id150"], [3, "id152"], [3, "id154"], [3, "id156"], [3, "id158"], [3, "id160"], [3, "id162"], [3, "id164"], [3, "id166"], [3, "id168"], [3, "id170"], [3, "id172"], [3, "id174"], [3, "id176"], [3, "id178"], [3, "id180"], [3, "id182"], [3, "id184"], [3, "id186"], [3, "id188"], [3, "id190"], [3, "id192"], [3, "id194"], [3, "id196"], [3, "id198"], [3, "id200"], [3, "id202"], [3, "id204"], [3, "id206"], [3, "id208"], [3, "id210"], [3, "id212"], [3, "id214"], [3, "id216"], [3, "id218"], [3, "id220"], [3, "id222"], [3, "id224"], [3, "id226"], [3, "id228"], [3, "id230"], [3, "id232"], [3, "id234"], [3, "id236"], [3, "id238"], [3, "id240"], [3, "id242"], [3, "id244"], [3, "id246"], [3, "id248"], [3, "id250"], [3, "id252"]], "Specification": [[1, "specification"], [2, "specification"], [4, "specification"], [3, "specification"]], ".metadata": [[1, "metadata"], [2, "metadata"], [4, "metadata"], [3, "metadata"]], "Type": [[1, "type"], [1, "id3"], [1, "id5"], [1, "id7"], [1, "id9"], [1, "id11"], [1, "id13"], [1, "id15"], [1, "id17"], [1, "id19"], [1, "id21"], [1, "id23"], [1, "id25"], [1, "id27"], [1, "id29"], [1, "id31"], [1, "id33"], [1, "id35"], [1, "id37"], [1, "id39"], [1, "id41"], [1, "id43"], [1, "id45"], [1, "id47"], [1, "id49"], [1, "id51"], [1, "id53"], [1, "id55"], [1, "id57"], [1, "id59"], [1, "id61"], [1, "id63"], [1, "id65"], [1, "id67"], [1, "id69"], [1, "id71"], [1, "id73"], [1, "id75"], [1, "id77"], [1, "id79"], [1, "id81"], [1, "id83"], [1, "id85"], [1, "id87"], [1, "id89"], [1, "id91"], [1, "id93"], [1, "id95"], [1, "id97"], [1, "id99"], [1, "id101"], [1, "id103"], [1, "id105"], [1, "id107"], [1, "id109"], [1, "id111"], [2, "type"], [2, "id3"], [2, "id5"], [2, "id7"], [2, "id9"], [2, "id11"], [2, "id13"], [2, "id15"], [2, "id17"], [2, "id19"], [2, "id21"], [2, "id23"], [2, "id25"], [2, "id27"], [2, "id29"], [2, "id31"], [2, "id33"], [2, "id35"], [2, "id37"], [2, "id39"], [2, "id41"], [2, "id43"], [2, "id45"], [2, "id47"], [2, "id49"], [2, "id51"], [2, "id53"], [2, "id55"], [2, "id57"], [2, "id59"], [2, "id61"], [2, "id63"], [2, "id65"], [2, "id67"], [2, "id69"], [2, "id71"], [2, "id73"], [2, "id75"], [2, "id77"], [2, "id79"], [2, "id81"], [2, "id83"], [2, "id85"], [2, "id87"], [2, "id89"], [2, "id91"], [2, "id93"], [2, "id95"], [2, "id97"], [2, "id99"], [2, "id101"], [2, "id103"], [2, "id105"], [2, "id107"], [2, "id109"], [2, "id111"], [2, "id113"], [2, "id115"], [2, "id117"], [2, "id119"], [2, "id121"], [2, "id123"], [2, "id125"], [2, "id127"], [2, "id129"], [2, "id131"], [2, "id133"], [2, "id135"], [2, "id137"], [2, "id139"], [2, "id141"], [2, "id143"], [2, "id145"], [2, "id147"], [2, "id149"], [2, "id151"], [2, "id153"], [2, "id155"], [2, "id157"], [2, "id159"], [2, "id161"], [2, "id163"], [2, "id165"], [2, "id167"], [2, "id169"], [2, "id171"], [2, "id173"], [2, "id175"], [2, "id177"], [2, "id179"], [2, "id181"], [2, "id183"], [2, "id185"], [2, "id187"], [2, "id189"], [2, "id191"], [2, "id193"], [2, "id195"], [2, "id197"], [2, "id199"], [2, "id201"], [2, "id203"], [2, "id205"], [2, "id207"], [2, "id209"], [2, "id211"], [2, "id213"], [2, "id215"], [2, "id217"], [2, "id219"], [2, "id221"], [2, "id223"], [2, "id225"], [2, "id227"], [2, "id229"], [2, "id231"], [2, "id233"], [2, "id235"], [2, "id237"], [2, "id239"], [2, "id241"], [2, "id243"], [2, "id245"], [2, "id247"], [2, "id249"], [2, "id251"], [2, "id253"], [2, "id255"], [2, "id257"], [2, "id259"], [2, "id261"], [2, "id263"], [2, "id265"], [2, "id267"], [2, "id269"], [2, "id271"], [2, "id273"], [2, "id275"], [2, "id277"], [2, "id279"], [2, "id281"], [2, "id283"], [2, "id285"], [2, "id287"], [2, "id289"], [2, "id291"], [2, "id293"], [2, "id295"], [2, "id297"], [2, "id299"], [2, "id301"], [4, "type"], [4, "id3"], [4, "id5"], [3, "type"], [3, "id3"], [3, "id5"], [3, "id7"], [3, "id9"], [3, "id11"], [3, "id13"], [3, "id15"], [3, "id17"], [3, "id19"], [3, "id21"], [3, "id23"], [3, "id25"], [3, "id27"], [3, "id29"], [3, "id31"], [3, "id33"], [3, "id35"], [3, "id37"], [3, "id39"], [3, "id41"], [3, "id43"], [3, "id45"], [3, "id47"], [3, "id49"], [3, "id51"], [3, "id53"], [3, "id55"], [3, "id57"], [3, "id59"], [3, "id61"], [3, "id63"], [3, "id65"], [3, "id67"], [3, "id69"], [3, "id71"], [3, "id73"], [3, "id75"], [3, "id77"], [3, "id79"], [3, "id81"], [3, "id83"], [3, "id85"], [3, "id87"], [3, "id89"], [3, "id91"], [3, "id93"], [3, "id95"], [3, "id97"], [3, "id99"], [3, "id101"], [3, "id103"], [3, "id105"], [3, "id107"], [3, "id109"], [3, "id111"], [3, "id113"], [3, "id115"], [3, "id117"], [3, "id119"], [3, "id121"], [3, "id123"], [3, "id125"], [3, "id127"], [3, "id129"], [3, "id131"], [3, "id133"], [3, "id135"], [3, "id137"], [3, "id139"], [3, "id141"], [3, "id143"], [3, "id145"], [3, "id147"], [3, "id149"], [3, "id151"], [3, "id153"], [3, "id155"], [3, "id157"], [3, "id159"], [3, "id161"], [3, "id163"], [3, "id165"], [3, "id167"], [3, "id169"], [3, "id171"], [3, "id173"], [3, "id175"], [3, "id177"], [3, "id179"], [3, "id181"], [3, "id183"], [3, "id185"], [3, "id187"], [3, "id189"], [3, "id191"], [3, "id193"], [3, "id195"], [3, "id197"], [3, "id199"], [3, "id201"], [3, "id203"], [3, "id205"], [3, "id207"], [3, "id209"], [3, "id211"], [3, "id213"], [3, "id215"], [3, "id217"], [3, "id219"], [3, "id221"], [3, "id223"], [3, "id225"], [3, "id227"], [3, "id229"], [3, "id231"], [3, "id233"], [3, "id235"], [3, "id237"], [3, "id239"], [3, "id241"], [3, "id243"], [3, "id245"], [3, "id247"], [3, "id249"], [3, "id251"], [3, "id253"]], ".spec": [[1, "spec"], [2, "spec"], [4, "spec"], [3, "spec"]], ".spec.localDiskSetup": [[1, "spec-localdisksetup"]], ".spec.localDiskSetup.filesystems[]": [[1, "spec-localdisksetup-filesystems"]], ".spec.localDiskSetup.mounts[]": [[1, "spec-localdisksetup-mounts"]], ".spec.localDiskSetup.raids[]": [[1, "spec-localdisksetup-raids"]], ".spec.localDiskSetup.raids[].RAID0": [[1, "spec-localdisksetup-raids-raid0"]], ".spec.localDiskSetup.raids[].RAID0.devices": [[1, "spec-localdisksetup-raids-raid0-devices"]], ".spec.placement": [[1, "spec-placement"]], ".spec.placement.affinity": [[1, "spec-placement-affinity"]], ".spec.placement.affinity.nodeAffinity": [[1, "spec-placement-affinity-nodeaffinity"]], ".spec.placement.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[1, "spec-placement-affinity-nodeaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.placement.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference": [[1, "spec-placement-affinity-nodeaffinity-preferredduringschedulingignoredduringexecution-preference"]], ".spec.placement.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchExpressions[]": [[1, "spec-placement-affinity-nodeaffinity-preferredduringschedulingignoredduringexecution-preference-matchexpressions"]], ".spec.placement.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchFields[]": [[1, "spec-placement-affinity-nodeaffinity-preferredduringschedulingignoredduringexecution-preference-matchfields"]], ".spec.placement.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution": [[1, "spec-placement-affinity-nodeaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.placement.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[]": [[1, "spec-placement-affinity-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms"]], ".spec.placement.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchExpressions[]": [[1, "spec-placement-affinity-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms-matchexpressions"]], ".spec.placement.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchFields[]": [[1, "spec-placement-affinity-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms-matchfields"]], ".spec.placement.affinity.podAffinity": [[1, "spec-placement-affinity-podaffinity"]], ".spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[1, "spec-placement-affinity-podaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm": [[1, "spec-placement-affinity-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm"]], ".spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector": [[1, "spec-placement-affinity-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector"]], ".spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]": [[1, "spec-placement-affinity-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchexpressions"]], ".spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels": [[1, "spec-placement-affinity-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchlabels"]], ".spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector": [[1, "spec-placement-affinity-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector"]], ".spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]": [[1, "spec-placement-affinity-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchexpressions"]], ".spec.placement.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels": [[1, "spec-placement-affinity-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchlabels"]], ".spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[]": [[1, "spec-placement-affinity-podaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector": [[1, "spec-placement-affinity-podaffinity-requiredduringschedulingignoredduringexecution-labelselector"]], ".spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]": [[1, "spec-placement-affinity-podaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchexpressions"]], ".spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels": [[1, "spec-placement-affinity-podaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchlabels"]], ".spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector": [[1, "spec-placement-affinity-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector"]], ".spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]": [[1, "spec-placement-affinity-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchexpressions"]], ".spec.placement.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels": [[1, "spec-placement-affinity-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchlabels"]], ".spec.placement.affinity.podAntiAffinity": [[1, "spec-placement-affinity-podantiaffinity"]], ".spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[1, "spec-placement-affinity-podantiaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm": [[1, "spec-placement-affinity-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm"]], ".spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector": [[1, "spec-placement-affinity-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector"]], ".spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]": [[1, "spec-placement-affinity-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchexpressions"]], ".spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels": [[1, "spec-placement-affinity-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchlabels"]], ".spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector": [[1, "spec-placement-affinity-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector"]], ".spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]": [[1, "spec-placement-affinity-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchexpressions"]], ".spec.placement.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels": [[1, "spec-placement-affinity-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchlabels"]], ".spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[]": [[1, "spec-placement-affinity-podantiaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector": [[1, "spec-placement-affinity-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector"]], ".spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]": [[1, "spec-placement-affinity-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchexpressions"]], ".spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels": [[1, "spec-placement-affinity-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchlabels"]], ".spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector": [[1, "spec-placement-affinity-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector"]], ".spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]": [[1, "spec-placement-affinity-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchexpressions"]], ".spec.placement.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels": [[1, "spec-placement-affinity-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchlabels"]], ".spec.placement.nodeSelector": [[1, "spec-placement-nodeselector"]], ".spec.placement.tolerations[]": [[1, "spec-placement-tolerations"]], ".status": [[1, "status"], [2, "status"], [4, "status"], [3, "status"]], ".status.conditions[]": [[1, "status-conditions"], [2, "status-conditions"], [3, "status-conditions"]], ".status.nodeStatuses[]": [[1, "status-nodestatuses"]], "API Reference": [[5, "api-reference"]], "API Groups and Kinds": [[5, "api-groups-and-kinds"]], "ScyllaCluster (scylla.scylladb.com/v1)": [[2, "scyllacluster-scylla-scylladb-com-v1"]], ".spec.alternator": [[2, "spec-alternator"]], ".spec.backups[]": [[2, "spec-backups"]], ".spec.datacenter": [[2, "spec-datacenter"]], ".spec.datacenter.racks[]": [[2, "spec-datacenter-racks"]], ".spec.datacenter.racks[].agentResources": [[2, "spec-datacenter-racks-agentresources"]], ".spec.datacenter.racks[].agentResources.claims[]": [[2, "spec-datacenter-racks-agentresources-claims"]], ".spec.datacenter.racks[].agentResources.limits": [[2, "spec-datacenter-racks-agentresources-limits"]], ".spec.datacenter.racks[].agentResources.requests": [[2, "spec-datacenter-racks-agentresources-requests"]], ".spec.datacenter.racks[].agentVolumeMounts[]": [[2, "spec-datacenter-racks-agentvolumemounts"]], ".spec.datacenter.racks[].placement": [[2, "spec-datacenter-racks-placement"]], ".spec.datacenter.racks[].placement.nodeAffinity": [[2, "spec-datacenter-racks-placement-nodeaffinity"]], ".spec.datacenter.racks[].placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[2, "spec-datacenter-racks-placement-nodeaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.datacenter.racks[].placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference": [[2, "spec-datacenter-racks-placement-nodeaffinity-preferredduringschedulingignoredduringexecution-preference"]], ".spec.datacenter.racks[].placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchExpressions[]": [[2, "spec-datacenter-racks-placement-nodeaffinity-preferredduringschedulingignoredduringexecution-preference-matchexpressions"]], ".spec.datacenter.racks[].placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchFields[]": [[2, "spec-datacenter-racks-placement-nodeaffinity-preferredduringschedulingignoredduringexecution-preference-matchfields"]], ".spec.datacenter.racks[].placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution": [[2, "spec-datacenter-racks-placement-nodeaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.datacenter.racks[].placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[]": [[2, "spec-datacenter-racks-placement-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms"]], ".spec.datacenter.racks[].placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchExpressions[]": [[2, "spec-datacenter-racks-placement-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms-matchexpressions"]], ".spec.datacenter.racks[].placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchFields[]": [[2, "spec-datacenter-racks-placement-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms-matchfields"]], ".spec.datacenter.racks[].placement.podAffinity": [[2, "spec-datacenter-racks-placement-podaffinity"]], ".spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[2, "spec-datacenter-racks-placement-podaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm": [[2, "spec-datacenter-racks-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm"]], ".spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector": [[2, "spec-datacenter-racks-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector"]], ".spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]": [[2, "spec-datacenter-racks-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchexpressions"]], ".spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels": [[2, "spec-datacenter-racks-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchlabels"]], ".spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector": [[2, "spec-datacenter-racks-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector"]], ".spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]": [[2, "spec-datacenter-racks-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchexpressions"]], ".spec.datacenter.racks[].placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels": [[2, "spec-datacenter-racks-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchlabels"]], ".spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[]": [[2, "spec-datacenter-racks-placement-podaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector": [[2, "spec-datacenter-racks-placement-podaffinity-requiredduringschedulingignoredduringexecution-labelselector"]], ".spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]": [[2, "spec-datacenter-racks-placement-podaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchexpressions"]], ".spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels": [[2, "spec-datacenter-racks-placement-podaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchlabels"]], ".spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector": [[2, "spec-datacenter-racks-placement-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector"]], ".spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]": [[2, "spec-datacenter-racks-placement-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchexpressions"]], ".spec.datacenter.racks[].placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels": [[2, "spec-datacenter-racks-placement-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchlabels"]], ".spec.datacenter.racks[].placement.podAntiAffinity": [[2, "spec-datacenter-racks-placement-podantiaffinity"]], ".spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[2, "spec-datacenter-racks-placement-podantiaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm": [[2, "spec-datacenter-racks-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm"]], ".spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector": [[2, "spec-datacenter-racks-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector"]], ".spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]": [[2, "spec-datacenter-racks-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchexpressions"]], ".spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels": [[2, "spec-datacenter-racks-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchlabels"]], ".spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector": [[2, "spec-datacenter-racks-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector"]], ".spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]": [[2, "spec-datacenter-racks-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchexpressions"]], ".spec.datacenter.racks[].placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels": [[2, "spec-datacenter-racks-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchlabels"]], ".spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[]": [[2, "spec-datacenter-racks-placement-podantiaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector": [[2, "spec-datacenter-racks-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector"]], ".spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]": [[2, "spec-datacenter-racks-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchexpressions"]], ".spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels": [[2, "spec-datacenter-racks-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchlabels"]], ".spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector": [[2, "spec-datacenter-racks-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector"]], ".spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]": [[2, "spec-datacenter-racks-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchexpressions"]], ".spec.datacenter.racks[].placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels": [[2, "spec-datacenter-racks-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchlabels"]], ".spec.datacenter.racks[].placement.tolerations[]": [[2, "spec-datacenter-racks-placement-tolerations"]], ".spec.datacenter.racks[].resources": [[2, "spec-datacenter-racks-resources"]], ".spec.datacenter.racks[].resources.claims[]": [[2, "spec-datacenter-racks-resources-claims"]], ".spec.datacenter.racks[].resources.limits": [[2, "spec-datacenter-racks-resources-limits"]], ".spec.datacenter.racks[].resources.requests": [[2, "spec-datacenter-racks-resources-requests"]], ".spec.datacenter.racks[].storage": [[2, "spec-datacenter-racks-storage"]], ".spec.datacenter.racks[].volumeMounts[]": [[2, "spec-datacenter-racks-volumemounts"]], ".spec.datacenter.racks[].volumes[]": [[2, "spec-datacenter-racks-volumes"]], ".spec.datacenter.racks[].volumes[].awsElasticBlockStore": [[2, "spec-datacenter-racks-volumes-awselasticblockstore"]], ".spec.datacenter.racks[].volumes[].azureDisk": [[2, "spec-datacenter-racks-volumes-azuredisk"]], ".spec.datacenter.racks[].volumes[].azureFile": [[2, "spec-datacenter-racks-volumes-azurefile"]], ".spec.datacenter.racks[].volumes[].cephfs": [[2, "spec-datacenter-racks-volumes-cephfs"]], ".spec.datacenter.racks[].volumes[].cephfs.secretRef": [[2, "spec-datacenter-racks-volumes-cephfs-secretref"]], ".spec.datacenter.racks[].volumes[].cinder": [[2, "spec-datacenter-racks-volumes-cinder"]], ".spec.datacenter.racks[].volumes[].cinder.secretRef": [[2, "spec-datacenter-racks-volumes-cinder-secretref"]], ".spec.datacenter.racks[].volumes[].configMap": [[2, "spec-datacenter-racks-volumes-configmap"]], ".spec.datacenter.racks[].volumes[].configMap.items[]": [[2, "spec-datacenter-racks-volumes-configmap-items"]], ".spec.datacenter.racks[].volumes[].csi": [[2, "spec-datacenter-racks-volumes-csi"]], ".spec.datacenter.racks[].volumes[].csi.nodePublishSecretRef": [[2, "spec-datacenter-racks-volumes-csi-nodepublishsecretref"]], ".spec.datacenter.racks[].volumes[].csi.volumeAttributes": [[2, "spec-datacenter-racks-volumes-csi-volumeattributes"]], ".spec.datacenter.racks[].volumes[].downwardAPI": [[2, "spec-datacenter-racks-volumes-downwardapi"]], ".spec.datacenter.racks[].volumes[].downwardAPI.items[]": [[2, "spec-datacenter-racks-volumes-downwardapi-items"]], ".spec.datacenter.racks[].volumes[].downwardAPI.items[].fieldRef": [[2, "spec-datacenter-racks-volumes-downwardapi-items-fieldref"]], ".spec.datacenter.racks[].volumes[].downwardAPI.items[].resourceFieldRef": [[2, "spec-datacenter-racks-volumes-downwardapi-items-resourcefieldref"]], ".spec.datacenter.racks[].volumes[].emptyDir": [[2, "spec-datacenter-racks-volumes-emptydir"]], ".spec.datacenter.racks[].volumes[].ephemeral": [[2, "spec-datacenter-racks-volumes-ephemeral"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.metadata": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-metadata"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-spec"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.dataSource": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-spec-datasource"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.dataSourceRef": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-spec-datasourceref"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.resources": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-spec-resources"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.resources.limits": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-spec-resources-limits"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.resources.requests": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-spec-resources-requests"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.selector": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-spec-selector"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.selector.matchExpressions[]": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-spec-selector-matchexpressions"]], ".spec.datacenter.racks[].volumes[].ephemeral.volumeClaimTemplate.spec.selector.matchLabels": [[2, "spec-datacenter-racks-volumes-ephemeral-volumeclaimtemplate-spec-selector-matchlabels"]], ".spec.datacenter.racks[].volumes[].fc": [[2, "spec-datacenter-racks-volumes-fc"]], ".spec.datacenter.racks[].volumes[].flexVolume": [[2, "spec-datacenter-racks-volumes-flexvolume"]], ".spec.datacenter.racks[].volumes[].flexVolume.options": [[2, "spec-datacenter-racks-volumes-flexvolume-options"]], ".spec.datacenter.racks[].volumes[].flexVolume.secretRef": [[2, "spec-datacenter-racks-volumes-flexvolume-secretref"]], ".spec.datacenter.racks[].volumes[].flocker": [[2, "spec-datacenter-racks-volumes-flocker"]], ".spec.datacenter.racks[].volumes[].gcePersistentDisk": [[2, "spec-datacenter-racks-volumes-gcepersistentdisk"]], ".spec.datacenter.racks[].volumes[].gitRepo": [[2, "spec-datacenter-racks-volumes-gitrepo"]], ".spec.datacenter.racks[].volumes[].glusterfs": [[2, "spec-datacenter-racks-volumes-glusterfs"]], ".spec.datacenter.racks[].volumes[].hostPath": [[2, "spec-datacenter-racks-volumes-hostpath"]], ".spec.datacenter.racks[].volumes[].iscsi": [[2, "spec-datacenter-racks-volumes-iscsi"]], ".spec.datacenter.racks[].volumes[].iscsi.secretRef": [[2, "spec-datacenter-racks-volumes-iscsi-secretref"]], ".spec.datacenter.racks[].volumes[].nfs": [[2, "spec-datacenter-racks-volumes-nfs"]], ".spec.datacenter.racks[].volumes[].persistentVolumeClaim": [[2, "spec-datacenter-racks-volumes-persistentvolumeclaim"]], ".spec.datacenter.racks[].volumes[].photonPersistentDisk": [[2, "spec-datacenter-racks-volumes-photonpersistentdisk"]], ".spec.datacenter.racks[].volumes[].portworxVolume": [[2, "spec-datacenter-racks-volumes-portworxvolume"]], ".spec.datacenter.racks[].volumes[].projected": [[2, "spec-datacenter-racks-volumes-projected"]], ".spec.datacenter.racks[].volumes[].projected.sources[]": [[2, "spec-datacenter-racks-volumes-projected-sources"]], ".spec.datacenter.racks[].volumes[].projected.sources[].clusterTrustBundle": [[2, "spec-datacenter-racks-volumes-projected-sources-clustertrustbundle"]], ".spec.datacenter.racks[].volumes[].projected.sources[].clusterTrustBundle.labelSelector": [[2, "spec-datacenter-racks-volumes-projected-sources-clustertrustbundle-labelselector"]], ".spec.datacenter.racks[].volumes[].projected.sources[].clusterTrustBundle.labelSelector.matchExpressions[]": [[2, "spec-datacenter-racks-volumes-projected-sources-clustertrustbundle-labelselector-matchexpressions"]], ".spec.datacenter.racks[].volumes[].projected.sources[].clusterTrustBundle.labelSelector.matchLabels": [[2, "spec-datacenter-racks-volumes-projected-sources-clustertrustbundle-labelselector-matchlabels"]], ".spec.datacenter.racks[].volumes[].projected.sources[].configMap": [[2, "spec-datacenter-racks-volumes-projected-sources-configmap"]], ".spec.datacenter.racks[].volumes[].projected.sources[].configMap.items[]": [[2, "spec-datacenter-racks-volumes-projected-sources-configmap-items"]], ".spec.datacenter.racks[].volumes[].projected.sources[].downwardAPI": [[2, "spec-datacenter-racks-volumes-projected-sources-downwardapi"]], ".spec.datacenter.racks[].volumes[].projected.sources[].downwardAPI.items[]": [[2, "spec-datacenter-racks-volumes-projected-sources-downwardapi-items"]], ".spec.datacenter.racks[].volumes[].projected.sources[].downwardAPI.items[].fieldRef": [[2, "spec-datacenter-racks-volumes-projected-sources-downwardapi-items-fieldref"]], ".spec.datacenter.racks[].volumes[].projected.sources[].downwardAPI.items[].resourceFieldRef": [[2, "spec-datacenter-racks-volumes-projected-sources-downwardapi-items-resourcefieldref"]], ".spec.datacenter.racks[].volumes[].projected.sources[].secret": [[2, "spec-datacenter-racks-volumes-projected-sources-secret"]], ".spec.datacenter.racks[].volumes[].projected.sources[].secret.items[]": [[2, "spec-datacenter-racks-volumes-projected-sources-secret-items"]], ".spec.datacenter.racks[].volumes[].projected.sources[].serviceAccountToken": [[2, "spec-datacenter-racks-volumes-projected-sources-serviceaccounttoken"]], ".spec.datacenter.racks[].volumes[].quobyte": [[2, "spec-datacenter-racks-volumes-quobyte"]], ".spec.datacenter.racks[].volumes[].rbd": [[2, "spec-datacenter-racks-volumes-rbd"]], ".spec.datacenter.racks[].volumes[].rbd.secretRef": [[2, "spec-datacenter-racks-volumes-rbd-secretref"]], ".spec.datacenter.racks[].volumes[].scaleIO": [[2, "spec-datacenter-racks-volumes-scaleio"]], ".spec.datacenter.racks[].volumes[].scaleIO.secretRef": [[2, "spec-datacenter-racks-volumes-scaleio-secretref"]], ".spec.datacenter.racks[].volumes[].secret": [[2, "spec-datacenter-racks-volumes-secret"]], ".spec.datacenter.racks[].volumes[].secret.items[]": [[2, "spec-datacenter-racks-volumes-secret-items"]], ".spec.datacenter.racks[].volumes[].storageos": [[2, "spec-datacenter-racks-volumes-storageos"]], ".spec.datacenter.racks[].volumes[].storageos.secretRef": [[2, "spec-datacenter-racks-volumes-storageos-secretref"]], ".spec.datacenter.racks[].volumes[].vsphereVolume": [[2, "spec-datacenter-racks-volumes-vspherevolume"]], ".spec.exposeOptions": [[2, "spec-exposeoptions"]], ".spec.exposeOptions.broadcastOptions": [[2, "spec-exposeoptions-broadcastoptions"]], ".spec.exposeOptions.broadcastOptions.clients": [[2, "spec-exposeoptions-broadcastoptions-clients"]], ".spec.exposeOptions.broadcastOptions.clients.podIP": [[2, "spec-exposeoptions-broadcastoptions-clients-podip"]], ".spec.exposeOptions.broadcastOptions.nodes": [[2, "spec-exposeoptions-broadcastoptions-nodes"]], ".spec.exposeOptions.broadcastOptions.nodes.podIP": [[2, "spec-exposeoptions-broadcastoptions-nodes-podip"]], ".spec.exposeOptions.cql": [[2, "spec-exposeoptions-cql"]], ".spec.exposeOptions.cql.ingress": [[2, "spec-exposeoptions-cql-ingress"]], ".spec.exposeOptions.cql.ingress.annotations": [[2, "spec-exposeoptions-cql-ingress-annotations"]], ".spec.exposeOptions.nodeService": [[2, "spec-exposeoptions-nodeservice"]], ".spec.exposeOptions.nodeService.annotations": [[2, "spec-exposeoptions-nodeservice-annotations"]], ".spec.genericUpgrade": [[2, "spec-genericupgrade"]], ".spec.imagePullSecrets[]": [[2, "spec-imagepullsecrets"]], ".spec.network": [[2, "spec-network"]], ".spec.repairs[]": [[2, "spec-repairs"]], ".status.backups[]": [[2, "status-backups"]], ".status.racks": [[2, "status-racks"]], ".status.repairs[]": [[2, "status-repairs"]], ".status.upgrade": [[2, "status-upgrade"]], "ScyllaOperatorConfig (scylla.scylladb.com/v1alpha1)": [[4, "scyllaoperatorconfig-scylla-scylladb-com-v1alpha1"]], "Contributing to Scylla Operator": [[6, "contributing-to-scylla-operator"]], "Initial Setup": [[6, "initial-setup"]], "Create a Fork": [[6, "create-a-fork"]], "Clone Your Fork": [[6, "clone-your-fork"]], "Add Upstream Remote": [[6, "add-upstream-remote"]], "Development": [[6, "development"]], "Building the project": [[6, "building-the-project"]], "Create a Branch": [[6, "create-a-branch"]], "Updating Your Fork": [[6, "updating-your-fork"]], "Submitting a Pull Request": [[6, "submitting-a-pull-request"]], "Commit History": [[6, "commit-history"]], "Commit messages": [[6, "commit-messages"]], "Submitting": [[6, "submitting"]], "Deploying Scylla on EKS": [[7, "deploying-scylla-on-eks"]], "EKS Setup": [[7, "eks-setup"]], "Creating an EKS cluster": [[7, "creating-an-eks-cluster"]], "Installing script third party dependencies": [[7, "installing-script-third-party-dependencies"]], "Deleting an EKS cluster": [[7, "deleting-an-eks-cluster"]], "ScyllaDBMonitoring (scylla.scylladb.com/v1alpha1)": [[3, "scylladbmonitoring-scylla-scylladb-com-v1alpha1"]], ".spec.components": [[3, "spec-components"]], ".spec.components.grafana": [[3, "spec-components-grafana"]], ".spec.components.grafana.authentication": [[3, "spec-components-grafana-authentication"]], ".spec.components.grafana.exposeOptions": [[3, "spec-components-grafana-exposeoptions"]], ".spec.components.grafana.exposeOptions.webInterface": [[3, "spec-components-grafana-exposeoptions-webinterface"]], ".spec.components.grafana.exposeOptions.webInterface.ingress": [[3, "spec-components-grafana-exposeoptions-webinterface-ingress"]], ".spec.components.grafana.exposeOptions.webInterface.ingress.annotations": [[3, "spec-components-grafana-exposeoptions-webinterface-ingress-annotations"]], ".spec.components.grafana.placement": [[3, "spec-components-grafana-placement"]], ".spec.components.grafana.placement.nodeAffinity": [[3, "spec-components-grafana-placement-nodeaffinity"]], ".spec.components.grafana.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-grafana-placement-nodeaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.components.grafana.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference": [[3, "spec-components-grafana-placement-nodeaffinity-preferredduringschedulingignoredduringexecution-preference"]], ".spec.components.grafana.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchExpressions[]": [[3, "spec-components-grafana-placement-nodeaffinity-preferredduringschedulingignoredduringexecution-preference-matchexpressions"]], ".spec.components.grafana.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchFields[]": [[3, "spec-components-grafana-placement-nodeaffinity-preferredduringschedulingignoredduringexecution-preference-matchfields"]], ".spec.components.grafana.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution": [[3, "spec-components-grafana-placement-nodeaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.components.grafana.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[]": [[3, "spec-components-grafana-placement-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms"]], ".spec.components.grafana.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchExpressions[]": [[3, "spec-components-grafana-placement-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms-matchexpressions"]], ".spec.components.grafana.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchFields[]": [[3, "spec-components-grafana-placement-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms-matchfields"]], ".spec.components.grafana.placement.podAffinity": [[3, "spec-components-grafana-placement-podaffinity"]], ".spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-grafana-placement-podaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm": [[3, "spec-components-grafana-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm"]], ".spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector": [[3, "spec-components-grafana-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector"]], ".spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]": [[3, "spec-components-grafana-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchexpressions"]], ".spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels": [[3, "spec-components-grafana-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchlabels"]], ".spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector": [[3, "spec-components-grafana-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector"]], ".spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]": [[3, "spec-components-grafana-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchexpressions"]], ".spec.components.grafana.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels": [[3, "spec-components-grafana-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchlabels"]], ".spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-grafana-placement-podaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector": [[3, "spec-components-grafana-placement-podaffinity-requiredduringschedulingignoredduringexecution-labelselector"]], ".spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]": [[3, "spec-components-grafana-placement-podaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchexpressions"]], ".spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels": [[3, "spec-components-grafana-placement-podaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchlabels"]], ".spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector": [[3, "spec-components-grafana-placement-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector"]], ".spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]": [[3, "spec-components-grafana-placement-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchexpressions"]], ".spec.components.grafana.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels": [[3, "spec-components-grafana-placement-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchlabels"]], ".spec.components.grafana.placement.podAntiAffinity": [[3, "spec-components-grafana-placement-podantiaffinity"]], ".spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-grafana-placement-podantiaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm": [[3, "spec-components-grafana-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm"]], ".spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector": [[3, "spec-components-grafana-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector"]], ".spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]": [[3, "spec-components-grafana-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchexpressions"]], ".spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels": [[3, "spec-components-grafana-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchlabels"]], ".spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector": [[3, "spec-components-grafana-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector"]], ".spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]": [[3, "spec-components-grafana-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchexpressions"]], ".spec.components.grafana.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels": [[3, "spec-components-grafana-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchlabels"]], ".spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-grafana-placement-podantiaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector": [[3, "spec-components-grafana-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector"]], ".spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]": [[3, "spec-components-grafana-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchexpressions"]], ".spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels": [[3, "spec-components-grafana-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchlabels"]], ".spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector": [[3, "spec-components-grafana-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector"]], ".spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]": [[3, "spec-components-grafana-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchexpressions"]], ".spec.components.grafana.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels": [[3, "spec-components-grafana-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchlabels"]], ".spec.components.grafana.placement.tolerations[]": [[3, "spec-components-grafana-placement-tolerations"]], ".spec.components.grafana.resources": [[3, "spec-components-grafana-resources"]], ".spec.components.grafana.resources.claims[]": [[3, "spec-components-grafana-resources-claims"]], ".spec.components.grafana.resources.limits": [[3, "spec-components-grafana-resources-limits"]], ".spec.components.grafana.resources.requests": [[3, "spec-components-grafana-resources-requests"]], ".spec.components.prometheus": [[3, "spec-components-prometheus"]], ".spec.components.prometheus.exposeOptions": [[3, "spec-components-prometheus-exposeoptions"]], ".spec.components.prometheus.exposeOptions.webInterface": [[3, "spec-components-prometheus-exposeoptions-webinterface"]], ".spec.components.prometheus.exposeOptions.webInterface.ingress": [[3, "spec-components-prometheus-exposeoptions-webinterface-ingress"]], ".spec.components.prometheus.exposeOptions.webInterface.ingress.annotations": [[3, "spec-components-prometheus-exposeoptions-webinterface-ingress-annotations"]], ".spec.components.prometheus.placement": [[3, "spec-components-prometheus-placement"]], ".spec.components.prometheus.placement.nodeAffinity": [[3, "spec-components-prometheus-placement-nodeaffinity"]], ".spec.components.prometheus.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-prometheus-placement-nodeaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.components.prometheus.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference": [[3, "spec-components-prometheus-placement-nodeaffinity-preferredduringschedulingignoredduringexecution-preference"]], ".spec.components.prometheus.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchExpressions[]": [[3, "spec-components-prometheus-placement-nodeaffinity-preferredduringschedulingignoredduringexecution-preference-matchexpressions"]], ".spec.components.prometheus.placement.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[].preference.matchFields[]": [[3, "spec-components-prometheus-placement-nodeaffinity-preferredduringschedulingignoredduringexecution-preference-matchfields"]], ".spec.components.prometheus.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution": [[3, "spec-components-prometheus-placement-nodeaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.components.prometheus.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[]": [[3, "spec-components-prometheus-placement-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms"]], ".spec.components.prometheus.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchExpressions[]": [[3, "spec-components-prometheus-placement-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms-matchexpressions"]], ".spec.components.prometheus.placement.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[].matchFields[]": [[3, "spec-components-prometheus-placement-nodeaffinity-requiredduringschedulingignoredduringexecution-nodeselectorterms-matchfields"]], ".spec.components.prometheus.placement.podAffinity": [[3, "spec-components-prometheus-placement-podaffinity"]], ".spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-prometheus-placement-podaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm": [[3, "spec-components-prometheus-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm"]], ".spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector": [[3, "spec-components-prometheus-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector"]], ".spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]": [[3, "spec-components-prometheus-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchexpressions"]], ".spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels": [[3, "spec-components-prometheus-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchlabels"]], ".spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector": [[3, "spec-components-prometheus-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector"]], ".spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]": [[3, "spec-components-prometheus-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchexpressions"]], ".spec.components.prometheus.placement.podAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels": [[3, "spec-components-prometheus-placement-podaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchlabels"]], ".spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-prometheus-placement-podaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector": [[3, "spec-components-prometheus-placement-podaffinity-requiredduringschedulingignoredduringexecution-labelselector"]], ".spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]": [[3, "spec-components-prometheus-placement-podaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchexpressions"]], ".spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels": [[3, "spec-components-prometheus-placement-podaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchlabels"]], ".spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector": [[3, "spec-components-prometheus-placement-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector"]], ".spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]": [[3, "spec-components-prometheus-placement-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchexpressions"]], ".spec.components.prometheus.placement.podAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels": [[3, "spec-components-prometheus-placement-podaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchlabels"]], ".spec.components.prometheus.placement.podAntiAffinity": [[3, "spec-components-prometheus-placement-podantiaffinity"]], ".spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-prometheus-placement-podantiaffinity-preferredduringschedulingignoredduringexecution"]], ".spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm": [[3, "spec-components-prometheus-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm"]], ".spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector": [[3, "spec-components-prometheus-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector"]], ".spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchExpressions[]": [[3, "spec-components-prometheus-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchexpressions"]], ".spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.labelSelector.matchLabels": [[3, "spec-components-prometheus-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-labelselector-matchlabels"]], ".spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector": [[3, "spec-components-prometheus-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector"]], ".spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchExpressions[]": [[3, "spec-components-prometheus-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchexpressions"]], ".spec.components.prometheus.placement.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution[].podAffinityTerm.namespaceSelector.matchLabels": [[3, "spec-components-prometheus-placement-podantiaffinity-preferredduringschedulingignoredduringexecution-podaffinityterm-namespaceselector-matchlabels"]], ".spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[]": [[3, "spec-components-prometheus-placement-podantiaffinity-requiredduringschedulingignoredduringexecution"]], ".spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector": [[3, "spec-components-prometheus-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector"]], ".spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchExpressions[]": [[3, "spec-components-prometheus-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchexpressions"]], ".spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].labelSelector.matchLabels": [[3, "spec-components-prometheus-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-labelselector-matchlabels"]], ".spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector": [[3, "spec-components-prometheus-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector"]], ".spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchExpressions[]": [[3, "spec-components-prometheus-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchexpressions"]], ".spec.components.prometheus.placement.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[].namespaceSelector.matchLabels": [[3, "spec-components-prometheus-placement-podantiaffinity-requiredduringschedulingignoredduringexecution-namespaceselector-matchlabels"]], ".spec.components.prometheus.placement.tolerations[]": [[3, "spec-components-prometheus-placement-tolerations"]], ".spec.components.prometheus.resources": [[3, "spec-components-prometheus-resources"]], ".spec.components.prometheus.resources.claims[]": [[3, "spec-components-prometheus-resources-claims"]], ".spec.components.prometheus.resources.limits": [[3, "spec-components-prometheus-resources-limits"]], ".spec.components.prometheus.resources.requests": [[3, "spec-components-prometheus-resources-requests"]], ".spec.components.prometheus.storage": [[3, "spec-components-prometheus-storage"]], ".spec.components.prometheus.storage.annotations": [[3, "spec-components-prometheus-storage-annotations"]], ".spec.components.prometheus.storage.labels": [[3, "spec-components-prometheus-storage-labels"]], ".spec.components.prometheus.storage.volumeClaimTemplate": [[3, "spec-components-prometheus-storage-volumeclaimtemplate"]], ".spec.components.prometheus.storage.volumeClaimTemplate.metadata": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-metadata"]], ".spec.components.prometheus.storage.volumeClaimTemplate.spec": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-spec"]], ".spec.components.prometheus.storage.volumeClaimTemplate.spec.dataSource": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-spec-datasource"]], ".spec.components.prometheus.storage.volumeClaimTemplate.spec.dataSourceRef": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-spec-datasourceref"]], ".spec.components.prometheus.storage.volumeClaimTemplate.spec.resources": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-spec-resources"]], ".spec.components.prometheus.storage.volumeClaimTemplate.spec.resources.limits": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-spec-resources-limits"]], ".spec.components.prometheus.storage.volumeClaimTemplate.spec.resources.requests": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-spec-resources-requests"]], ".spec.components.prometheus.storage.volumeClaimTemplate.spec.selector": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-spec-selector"]], ".spec.components.prometheus.storage.volumeClaimTemplate.spec.selector.matchExpressions[]": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-spec-selector-matchexpressions"]], ".spec.components.prometheus.storage.volumeClaimTemplate.spec.selector.matchLabels": [[3, "spec-components-prometheus-storage-volumeclaimtemplate-spec-selector-matchlabels"]], ".spec.endpointsSelector": [[3, "spec-endpointsselector"]], ".spec.endpointsSelector.matchExpressions[]": [[3, "spec-endpointsselector-matchexpressions"]], ".spec.endpointsSelector.matchLabels": [[3, "spec-endpointsselector-matchlabels"]], "scylla.scylladb.com": [[0, "scylla-scylladb-com"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/master/sitemap.xml b/master/sitemap.xml new file mode 100644 index 00000000000..cf07eba455c --- /dev/null +++ b/master/sitemap.xml @@ -0,0 +1,2 @@ + +https://operator.docs.scylladb.com/stable/api-reference/groups/scylla.scylladb.com.htmlhttps://operator.docs.scylladb.com/stable/api-reference/groups/scylla.scylladb.com/nodeconfigs.htmlhttps://operator.docs.scylladb.com/stable/api-reference/groups/scylla.scylladb.com/scyllaclusters.htmlhttps://operator.docs.scylladb.com/stable/helm.htmlhttps://operator.docs.scylladb.com/stable/index.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/index.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/maintenance-mode.htmlhttps://operator.docs.scylladb.com/stable/manager.htmlhttps://operator.docs.scylladb.com/stable/migration.htmlhttps://operator.docs.scylladb.com/stable/api-reference/groups/scylla.scylladb.com/scylladbmonitorings.htmlhttps://operator.docs.scylladb.com/stable/monitoring.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/replace-node.htmlhttps://operator.docs.scylladb.com/stable/api-reference/groups/scylla.scylladb.com/scyllaoperatorconfigs.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/restore.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/scylla-upgrade.htmlhttps://operator.docs.scylladb.com/stable/multidc/eks.htmlhttps://operator.docs.scylladb.com/stable/multidc/gke.htmlhttps://operator.docs.scylladb.com/stable/api-reference/index.htmlhttps://operator.docs.scylladb.com/stable/multidc/index.htmlhttps://operator.docs.scylladb.com/stable/contributing.htmlhttps://operator.docs.scylladb.com/stable/performance.htmlhttps://operator.docs.scylladb.com/stable/multidc/multidc.htmlhttps://operator.docs.scylladb.com/stable/releases.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/automatic-cleanup.htmlhttps://operator.docs.scylladb.com/stable/support/index.htmlhttps://operator.docs.scylladb.com/stable/eks.htmlhttps://operator.docs.scylladb.com/stable/exposing.htmlhttps://operator.docs.scylladb.com/stable/support/overview.htmlhttps://operator.docs.scylladb.com/stable/generic.htmlhttps://operator.docs.scylladb.com/stable/support/known-issues.htmlhttps://operator.docs.scylladb.com/stable/support/troubleshooting/index.htmlhttps://operator.docs.scylladb.com/stable/support/must-gather.htmlhttps://operator.docs.scylladb.com/stable/gke.htmlhttps://operator.docs.scylladb.com/stable/support/troubleshooting/installation.htmlhttps://operator.docs.scylladb.com/stable/upgrade.htmlhttps://operator.docs.scylladb.com/stable/genindex.htmlhttps://operator.docs.scylladb.com/stable/404.htmlhttps://operator.docs.scylladb.com/stable/search.html \ No newline at end of file diff --git a/master/support/index.html b/master/support/index.html new file mode 100644 index 00000000000..0c2d4d0bcff --- /dev/null +++ b/master/support/index.html @@ -0,0 +1,597 @@ + + + + + + + + + + + + + Support | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Support

      + +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/support/known-issues.html b/master/support/known-issues.html new file mode 100644 index 00000000000..2b14c939380 --- /dev/null +++ b/master/support/known-issues.html @@ -0,0 +1,620 @@ + + + + + + + + + + + + + Known issues | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Known issues

      +
      +

      Scylla Manager does not boot up on Minikube

      +

      If your Scylla Manager is failing to apply 8th migration (008_*), then apply fix for TRUNCATE queries.

      +
      +
      +

      TRUNCATE queries does not work on Minikube

      +

      The TRUNCATE queries requires hairpinning to be enabled. On minikube this is disabled by default.

      +

      To fix it execute the following command:

      +
      minikube ssh sudo ip link set docker0 promisc on
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/support/must-gather.html b/master/support/must-gather.html new file mode 100644 index 00000000000..69e592d352b --- /dev/null +++ b/master/support/must-gather.html @@ -0,0 +1,707 @@ + + + + + + + + + + + + + Gathering data with must-gather | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Gathering data with must-gather

      +

      must-gather is an embedded tool in Scylla Operator that helps collecting all the necessary info when something goes wrong.

      +

      The tool talks to the Kubernetes API, retrieves a predefined set of resources and saves them into a folder in your current directory. +By default, all collected Secrets are censored to avoid sending sensitive data. +That said, you can always review the archive before you attach it to an issue or your support request.

      +

      Given it needs to talk to the Kubernetes API, at the very least, you need to supply the --kubeconfig flag with a path to the kubeconfig file for your Kubernetes cluster, or set the KUBECONFIG environment variable.

      +
      +

      Running must-gather

      +

      There is more than one way to run must-gather. +Here are some examples of how you can run the tool.

      +
      +

      Prerequisites

      +

      All examples assume you have exported KUBECONFIG environment variable that points to a kubeconfig file on your machine. +If not, you can run this command to export the common default location. +Please make sure such a file exists.

      +
      export KUBECONFIG=~/.kube/config
      +ls -l "${KUBECONFIG}"
      +
      +
      +
      +

      Note

      +

      There can be slight deviations in the arguments for your container tool, depending on the container runtime, whether you use SELinux or similar factors.

      +

      As an example, the need for the Z option on volume mounts depends on whether you use SELinux and what context is applied on your file or directory. +If you get an error mentioning Error: lsetxattr <path>: operation not supported, try it without the Z option.

      +
      +

      Let’s also check whether your kubeconfig uses external authentication plugin. +You can determine that by running

      +
      kubectl config view --minify
      +
      +
      +

      and checking whether it uses an external exec plugin by looking for this pattern (containing the exec key)

      +
      users:
      +- name: <user_name>
      +  user:
      +    exec:
      +
      +
      +

      If not, you can skip the rest of this section.

      +

      In case your kubeconfig depends on external binaries, you have to take a few extra steps because the external binary won’t be available within our container to authenticate the requests.

      +

      Similarly to how Pods are run within Kubernetes, we’ll create a dedicated ServiceAccount for must-gather and use it to run the tool. +(When you are done using it, feel free to remove the Kubernetes resources created for that purpose.)

      +
      kubectl create namespace must-gather
      +kubectl -n must-gather create serviceaccount must-gather
      +kubectl create clusterrolebinding must-gather --clusterrole=cluster-admin --serviceaccount=must-gather:must-gather
      +export MUST_GATHER_TOKEN
      +MUST_GATHER_TOKEN=$( kubectl -n must-gather create token must-gather --duration=1h )
      +kubeconfig=$( mktemp )
      +# Create a copy of the existing kubeconfig and
      +# replace user authentication using yq, or by adjusting the fields manually.
      +kubectl config view --minify --raw -o yaml | yq -e '.users[0].user = {"token": env(MUST_GATHER_TOKEN)}' > "${kubeconfig}"
      +KUBECONFIG="${kubeconfig}"
      +
      +
      +
      +

      Note

      +

      If you don’t have yq installed, you can get it at https://github.com/mikefarah/yq/#install or you can replace the user authentication settings manually.

      +
      +
      +
      +

      Podman

      +
      podman run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro,Z" -v="$( pwd ):/workspace:Z" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig
      +
      +
      +
      +
      +

      Docker

      +
      docker run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro" -v="$( pwd ):/workspace" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig
      +
      +
      +
      +
      +
      +

      Limiting must-gather to a particular namespace

      +

      If you are running a large Kubernetes cluster with many ScyllaClusters, it may be useful to limit the collection of ScyllaClusters to a particular namespace. +Unless you hit scale issues, we advise not to use this mode, as sometimes the ScyllaClusters affect other collected resources, like the manager or they form a multi-datacenter.

      +
      scylla-operator must-gather --namespace="<namespace_with_broken_scyllacluster>"
      +
      +
      +
      +

      Note

      +

      The --namespace flag affects only ScyllaClusters. +Other resources related to the operator installation or cluster state will still be collected from other namespaces.

      +
      +
      +

      Collecting every resource in the cluster

      +

      By default, must-gather collects only a predefined subset of resources. +You can also request collecting every resource in the Kubernetes API, if the default set wouldn’t be enough to debug an issue.

      +
      scylla-operator must-gather --all-resources
      +
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/support/overview.html b/master/support/overview.html new file mode 100644 index 00000000000..1adeb4f5516 --- /dev/null +++ b/master/support/overview.html @@ -0,0 +1,622 @@ + + + + + + + + + + + + + Support overview | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Support overview

      +
      +

      Get support

      +

      ScyllaDB provides administrators with paid support, including Scylla Operator.

      +
      +
      +

      Troubleshooting issues

      +

      To learn more about what to do when issues arise, visit our dedicated troubleshooting section.

      +
      +
      +

      Gather data about your cluster

      +

      Scylla Operator contains an embedded tool called must-gather that can collect the required information for requesting support or reporting issues. +Support requests and bug reports are required to attach the must-gather archive to help us understand the issue.

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/support/troubleshooting/index.html b/master/support/troubleshooting/index.html new file mode 100644 index 00000000000..612eb02e914 --- /dev/null +++ b/master/support/troubleshooting/index.html @@ -0,0 +1,603 @@ + + + + + + + + + + + + + Troubleshooting | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Troubleshooting

      + +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/support/troubleshooting/installation.html b/master/support/troubleshooting/installation.html new file mode 100644 index 00000000000..9b485898557 --- /dev/null +++ b/master/support/troubleshooting/installation.html @@ -0,0 +1,658 @@ + + + + + + + + + + + + + Troubleshooting installation issues | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Troubleshooting installation issues

      +
      +

      Webhooks

      +

      Scylla Operator provides several custom API resources that use webhooks to function properly.

      +

      Unfortunately, it is often the case that user’s clusters have modified SDN, that doesn’t extend to the control plane, and Kubernetes apiserver is not able to reach the pods that serve the webhook traffic. +Another common case are firewall rules that block the webhook traffic.

      +
      +

      Note

      +

      To be called a Kubernetes cluster, clusters are required to pass Kubernetes conformance test suite. +This suite includes tests that require Kubernetes apiserver to be able to reach webhook services.

      +
      +
      +

      Note

      +

      Before filing an issue, please make sure your cluster webhook traffic can reach your webhook services, independently of Scylla Operator resources.

      +
      +
      +

      EKS

      +
      +

      Custom CNI

      +

      EKS is currently breaking Kubernetes webhooks when used with custom CNI networking.

      +
      +

      Note

      +

      We advise you to avoid using such setups and use a conformant Kubernetes cluster that supports webhooks.

      +
      +

      There are some workarounds where you can reconfigure the webhook to use Ingress or hostNetwork instead, but it’s beyond a standard configuration that we support and not specific to the Scylla Operator.

      +
      +
      +
      +

      GKE

      +
      +

      Private clusters

      +

      If you use GKE private clusters you need to manually configure the firewall to allow webhook traffic. +You can find more information on how to do that in GKE private clusters docs.

      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/upgrade.html b/master/upgrade.html new file mode 100644 index 00000000000..e09f932a3e6 --- /dev/null +++ b/master/upgrade.html @@ -0,0 +1,811 @@ + + + + + + + + + + + + + Upgrade of Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

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

      +
      + + + +
      + +
      + +
      +

      Upgrade of Scylla Operator

      +

      This page describes Scylla Operator upgrade procedures.
      +There are two generic update procedures - via Helm and via kubectl. Before upgrading, please check this page to find out +if your target version requires additional upgrade steps.

      +
      +

      Upgrade via Helm

      +

      Helm doesn’t support managing CustomResourceDefinition resources (#5871, #7735)
      +These are only created on first install and never updated. In order to update them, users have to do it manually.

      +

      Replace <release_name> with the name of your Helm release for Scylla Operator and replace <version> with the version number you want to install:

      +
        +
      1. Make sure Helm chart repository is up-to-date:

        +
        helm repo add scylla-operator https://storage.googleapis.com/scylla-operator-charts/stable
        +helm repo update
        +
        +
        +
      2. +
      3. Update CRD resources. We recommend using --server-side flag for kubectl apply, if your version supports it.

        +
        tmpdir=$( mktemp -d ) \
        +  && helm pull scylla-operator/scylla-operator --version <version> --untar --untardir "${tmpdir}" \
        +  && find "${tmpdir}"/scylla-operator/crds/ -name '*.yaml' -printf '-f=%p ' \
        +  | xargs kubectl apply
        +
        +
        +
      4. +
      5. Update Scylla Operator

        +
        helm upgrade --version <version> <release_name> scylla-operator/scylla-operator
        +
        +
        +
      6. +
      +
      +
      +

      Upgrade via kubectl

      +

      Replace <version> with the version number you want to install:

      +
        +
      1. Checkout source code of version you want to use:

        +
        git checkout <version>
        +
        +
        +
      2. +
      3. Manifests use rolling minor version tag, you may want to pin it to specific version:

        +
        find deploy/operator -name "*.yaml" | xargs sed --follow-symlinks -i -E "s^docker.io/scylladb/scylla-operator:[0-9]+\.[0-9]+^docker.io/scylladb/scylla-operator:<version>^g"
        +
        +
        +
      4. +
      5. Update Scylla Operator. We recommend using --server-side flag for kubectl apply, if your version supports it.

        +
        kubectl apply -f deploy/operator
        +
        +
        +
      6. +
      +
      +
      +
      +

      v1.2.0 -> v1.3.0

      +

      Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

      +
        +
      1. Checkout source code of v1.3.0:

        +
        git checkout v1.3.0
        +
        +
        +
      2. +
      3. Update Scylla Operator from deploy directory:

        +
        kubectl -n scylla-operator apply -f deploy/operator
        +
        +
        +
      4. +
      5. Wait until Scylla Operator is up and running:

        +
        kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
        +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
        +
        +
        +
      6. +
      +
      +
      +

      v1.1.0 -> v1.2.0

      +

      1.2.0 release brought a lot of changes to the Scylla Operator deployment process. +To properly update Scylla Operator one must delete old objects and install updated ones.

      +

      Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

      +
        +
      1. Checkout source code of v1.2.0:

        +
        git checkout v1.2.0
        +
        +
        +
      2. +
      3. Remove old scylla operator namespace - in our case it’s called scylla-operator-system:

        +
        kubectl delete namespace scylla-operator-system --wait=true
        +
        +
        +
      4. +
      5. Remove old webhooks:

        +
        kubectl delete MutatingWebhookConfiguration scylla-operator-mutating-webhook-configuration
        +kubectl delete ValidatingWebhookConfiguration scylla-operator-validating-webhook-configuration
        +
        +
        +
      6. +
      7. Install Scylla Operator from deploy directory:

        +
        kubectl -n scylla-operator apply -f deploy/operator
        +
        +
        +
      8. +
      9. Wait until Scylla Operator is up and running:

        +
        kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
        +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
        +
        +
        +
      10. +
      +
      +
      +

      v1.0.0 -> v1.1.0

      +

      During this update we will change probes and image for Scylla Operator. +A new version brings an automation for upgrade of sidecar image, so a rolling restart of managed Scylla clusters is expected.

      +
        +
      1. Get name of StatefulSet managing Scylla Operator

        +
        kubectl --namespace scylla-operator-system get sts --selector="control-plane=controller-manager"
        +
        +NAME                                 READY   AGE
        +scylla-operator-controller-manager   1/1     95m
        +
        +
        +
      2. +
      3. Change probes and used container image by applying following patch:

        +
        spec:
        +  template:
        +    spec:
        +      containers:
        +      - name: manager
        +        image: docker.io/scylladb/scylla-operator:1.1.0
        +        livenessProbe:
        +          httpGet:
        +            path: /healthz
        +            port: 8080
        +            scheme: HTTP
        +        readinessProbe:
        +          $retainKeys:
        +          - httpGet
        +          httpGet:
        +            path: /readyz
        +            port: 8080
        +            scheme: HTTP
        +
        +
        +

        To apply above patch save it to file (operator-patch.yaml for example) and apply to Operator StatefulSet:

        +
        kubectl -n scylla-operator-system patch sts scylla-operator-controller-manager --patch "$(cat operator-patch.yaml)"
        +
        +
        +
      4. +
      +
      +
      +

      v0.3.0 -> v1.0.0

      +

      Note: There’s an experimental migration procedure available here.

      +

      v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common +kind which is easier to disambiguate. (ScyllaCluster). +This change is backward incompatible, so Scylla cluster must be turned off and recreated from scratch. +In case you need to preserve your data, refer to backup and restore guide.

      +
        +
      1. Get list of existing Scylla clusters

        +
        kubectl -n scylla get cluster.scylla.scylladb.com
        +
        +NAME             AGE
        +simple-cluster   30m
        +
        +
        +
      2. +
      3. Delete each one of them

        +
        kubectl -n scylla delete cluster.scylla.scylladb.com simple-cluster
        +
        +
        +
      4. +
      5. Make sure you’re on v0.3.0 branch

        +
        git checkout v0.3.0
        +
        +
        +
      6. +
      7. Delete existing CRD and Operator

        +
        kubectl delete -f examples/generic/operator.yaml
        +
        +
        +
      8. +
      9. Checkout v1.0.0 version

        +
        git checkout v1.0.0
        +
        +
        +
      10. +
      11. Install new CRD and Scylla Operator

        +
        kubectl apply -f deploy/operator.yaml
        +
        +
        +
      12. +
      13. Migrate your existing Scylla Cluster definition. Change apiVersion and kind from:

        +
        apiVersion: scylla.scylladb.com/v1alpha1
        +kind: Cluster
        +
        +
        +

        to:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +
        +
        +
      14. +
      15. Once your cluster definition is ready, use kubectl apply to install fresh Scylla cluster.

      16. +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/stable/.buildinfo b/stable/.buildinfo new file mode 100644 index 00000000000..ca144966e8a --- /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: a7e55cbf26668b392cfc9fabddb97157 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/stable/.doctrees/contributing.doctree b/stable/.doctrees/contributing.doctree new file mode 100644 index 00000000000..383c89e83bb Binary files /dev/null and b/stable/.doctrees/contributing.doctree differ diff --git a/stable/.doctrees/eks.doctree b/stable/.doctrees/eks.doctree new file mode 100644 index 00000000000..d1356dcd6d5 Binary files /dev/null and b/stable/.doctrees/eks.doctree differ diff --git a/stable/.doctrees/environment.pickle b/stable/.doctrees/environment.pickle new file mode 100644 index 00000000000..3484c7911d0 Binary files /dev/null and b/stable/.doctrees/environment.pickle differ diff --git a/stable/.doctrees/exposing.doctree b/stable/.doctrees/exposing.doctree new file mode 100644 index 00000000000..1402c618cb0 Binary files /dev/null and b/stable/.doctrees/exposing.doctree differ diff --git a/stable/.doctrees/generic.doctree b/stable/.doctrees/generic.doctree new file mode 100644 index 00000000000..e4c33ccbe98 Binary files /dev/null and b/stable/.doctrees/generic.doctree differ diff --git a/stable/.doctrees/gke.doctree b/stable/.doctrees/gke.doctree new file mode 100644 index 00000000000..363af21e0d5 Binary files /dev/null and b/stable/.doctrees/gke.doctree differ diff --git a/stable/.doctrees/helm.doctree b/stable/.doctrees/helm.doctree new file mode 100644 index 00000000000..072325f9e01 Binary files /dev/null and b/stable/.doctrees/helm.doctree differ diff --git a/stable/.doctrees/index.doctree b/stable/.doctrees/index.doctree new file mode 100644 index 00000000000..28cfaf18306 Binary files /dev/null and b/stable/.doctrees/index.doctree differ diff --git a/stable/.doctrees/manager.doctree b/stable/.doctrees/manager.doctree new file mode 100644 index 00000000000..112c48cb31c Binary files /dev/null and b/stable/.doctrees/manager.doctree differ diff --git a/stable/.doctrees/migration.doctree b/stable/.doctrees/migration.doctree new file mode 100644 index 00000000000..8fabad70fd2 Binary files /dev/null and b/stable/.doctrees/migration.doctree differ diff --git a/stable/.doctrees/monitoring.doctree b/stable/.doctrees/monitoring.doctree new file mode 100644 index 00000000000..feac013e77e Binary files /dev/null and b/stable/.doctrees/monitoring.doctree differ diff --git a/stable/.doctrees/multidc/eks.doctree b/stable/.doctrees/multidc/eks.doctree new file mode 100644 index 00000000000..b7c9bc6035d Binary files /dev/null and b/stable/.doctrees/multidc/eks.doctree differ diff --git a/stable/.doctrees/multidc/gke.doctree b/stable/.doctrees/multidc/gke.doctree new file mode 100644 index 00000000000..cd2da52e8e1 Binary files /dev/null and b/stable/.doctrees/multidc/gke.doctree differ diff --git a/stable/.doctrees/multidc/index.doctree b/stable/.doctrees/multidc/index.doctree new file mode 100644 index 00000000000..c7f658485a2 Binary files /dev/null and b/stable/.doctrees/multidc/index.doctree differ diff --git a/stable/.doctrees/multidc/multidc.doctree b/stable/.doctrees/multidc/multidc.doctree new file mode 100644 index 00000000000..77d540ba620 Binary files /dev/null and b/stable/.doctrees/multidc/multidc.doctree differ diff --git a/stable/.doctrees/nodeoperations/automatic-cleanup.doctree b/stable/.doctrees/nodeoperations/automatic-cleanup.doctree new file mode 100644 index 00000000000..99a6ba52b53 Binary files /dev/null and b/stable/.doctrees/nodeoperations/automatic-cleanup.doctree differ diff --git a/stable/.doctrees/nodeoperations/index.doctree b/stable/.doctrees/nodeoperations/index.doctree new file mode 100644 index 00000000000..97e2fc5f4a9 Binary files /dev/null and b/stable/.doctrees/nodeoperations/index.doctree differ diff --git a/stable/.doctrees/nodeoperations/maintenance-mode.doctree b/stable/.doctrees/nodeoperations/maintenance-mode.doctree new file mode 100644 index 00000000000..ee7053fc197 Binary files /dev/null and b/stable/.doctrees/nodeoperations/maintenance-mode.doctree differ diff --git a/stable/.doctrees/nodeoperations/replace-node.doctree b/stable/.doctrees/nodeoperations/replace-node.doctree new file mode 100644 index 00000000000..44d903063ee Binary files /dev/null and b/stable/.doctrees/nodeoperations/replace-node.doctree differ diff --git a/stable/.doctrees/nodeoperations/restore.doctree b/stable/.doctrees/nodeoperations/restore.doctree new file mode 100644 index 00000000000..f98972c2ae1 Binary files /dev/null and b/stable/.doctrees/nodeoperations/restore.doctree differ diff --git a/stable/.doctrees/nodeoperations/scylla-upgrade.doctree b/stable/.doctrees/nodeoperations/scylla-upgrade.doctree new file mode 100644 index 00000000000..980a53e217e Binary files /dev/null and b/stable/.doctrees/nodeoperations/scylla-upgrade.doctree differ diff --git a/stable/.doctrees/performance.doctree b/stable/.doctrees/performance.doctree new file mode 100644 index 00000000000..d18f60d4f59 Binary files /dev/null and b/stable/.doctrees/performance.doctree differ diff --git a/stable/.doctrees/releases.doctree b/stable/.doctrees/releases.doctree new file mode 100644 index 00000000000..0e405985882 Binary files /dev/null and b/stable/.doctrees/releases.doctree differ diff --git a/stable/.doctrees/scylla-cluster-crd.doctree b/stable/.doctrees/scylla-cluster-crd.doctree new file mode 100644 index 00000000000..cefa778bf49 Binary files /dev/null and b/stable/.doctrees/scylla-cluster-crd.doctree differ diff --git a/stable/.doctrees/support/index.doctree b/stable/.doctrees/support/index.doctree new file mode 100644 index 00000000000..024eaf45c62 Binary files /dev/null and b/stable/.doctrees/support/index.doctree differ diff --git a/stable/.doctrees/support/known-issues.doctree b/stable/.doctrees/support/known-issues.doctree new file mode 100644 index 00000000000..5a1553e35a1 Binary files /dev/null and b/stable/.doctrees/support/known-issues.doctree differ diff --git a/stable/.doctrees/support/must-gather.doctree b/stable/.doctrees/support/must-gather.doctree new file mode 100644 index 00000000000..c0b4667a8d7 Binary files /dev/null and b/stable/.doctrees/support/must-gather.doctree differ diff --git a/stable/.doctrees/support/overview.doctree b/stable/.doctrees/support/overview.doctree new file mode 100644 index 00000000000..16ad04ebc0c Binary files /dev/null and b/stable/.doctrees/support/overview.doctree differ diff --git a/stable/.doctrees/support/troubleshooting/index.doctree b/stable/.doctrees/support/troubleshooting/index.doctree new file mode 100644 index 00000000000..8f579834b91 Binary files /dev/null and b/stable/.doctrees/support/troubleshooting/index.doctree differ diff --git a/stable/.doctrees/support/troubleshooting/installation.doctree b/stable/.doctrees/support/troubleshooting/installation.doctree new file mode 100644 index 00000000000..51f268af8f4 Binary files /dev/null and b/stable/.doctrees/support/troubleshooting/installation.doctree differ diff --git a/stable/.doctrees/upgrade.doctree b/stable/.doctrees/upgrade.doctree new file mode 100644 index 00000000000..677cdd4c224 Binary files /dev/null and b/stable/.doctrees/upgrade.doctree differ diff --git a/stable/.nojekyll b/stable/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/stable/404.html b/stable/404.html new file mode 100644 index 00000000000..067dc99ea74 --- /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 00000000000..12aae904168 --- /dev/null +++ b/stable/CNAME @@ -0,0 +1 @@ +operator.docs.scylladb.com \ No newline at end of file diff --git a/stable/_images/clusterip.svg b/stable/_images/clusterip.svg new file mode 100644 index 00000000000..1c74e5e69ba --- /dev/null +++ b/stable/_images/clusterip.svg @@ -0,0 +1,3 @@ + + +
      Service
      ClusterIP
      10.0.0.1
      Servi...
      Service
      ClusterIP
      10.0.0.2
      Servi...
      Service
      ClusterIP
      10.0.0.3
      Servi...
      Pod
      Client
      Pod...
      Kubernetes cluster
      Kubernetes cluster
      Text is not SVG - cannot display
      \ No newline at end of file diff --git a/stable/_images/loadbalancer.svg b/stable/_images/loadbalancer.svg new file mode 100644 index 00000000000..c86a9a2a46b --- /dev/null +++ b/stable/_images/loadbalancer.svg @@ -0,0 +1,3 @@ + + +
      Service
      LoadBalancer
      Servi...
      Service
      LoadBalancer
      Servi...
      Service
      LoadBalancer
      Servi...
      Kubernetes cluster
      Kubernetes cluster
      VPC
      VPC
      Cloud Load
      Balancing
      Cloud...
      Cloud Load
      Balancing
      Cloud...
      Cloud Load
      Balancing
      Cloud...
      Client
      Client
      Internet
      Internet
      Text is not SVG - cannot display
      \ No newline at end of file diff --git a/stable/_images/logo.png b/stable/_images/logo.png new file mode 100644 index 00000000000..5bbfedad2ac Binary files /dev/null and b/stable/_images/logo.png differ diff --git a/stable/_images/multivpc.svg b/stable/_images/multivpc.svg new file mode 100644 index 00000000000..96fdcd7a536 --- /dev/null +++ b/stable/_images/multivpc.svg @@ -0,0 +1,3 @@ + + +
      Kubernetes cluster
      Kubernetes cluster
      Virtual Machine
      Client
      10.0.0.4
      Virtu...
      VPC A
      VPC A
      Pod
      Client
      20.0.0.5
      Pod...
      Kubernetes cluster
      Kubernetes cluster
      Virtual Machine
      Client
      20.0.0.4
      Virtu...
      VPC B
      VPC B
      Pod
      Client
      10.0.0.5
      Pod...
      VPC Peering
      VPC Peering


      Service
      Headless
      Service...


      Service
      Headless
      Service...


      Service
      Headless
      Service...


      Service
      Headless
      Service...


      Service
      Headless
      Service...


      Service
      Headless
      Service...
      PodIP: 10.0.0.3
      PodIP: 10.0.0...
      PodIP: 10.0.0.2
      PodIP: 10.0.0...
      PodIP: 10.0.0.1
      PodIP: 10.0.0...
      PodIP: 20.0.0.1
      PodIP: 20.0.0...
      PodIP: 20.0.0.2
      PodIP: 20.0.0...
      PodIP: 20.0.0.1
      PodIP: 20.0.0...
      Text is not SVG - cannot display
      \ No newline at end of file diff --git a/stable/_images/podips.svg b/stable/_images/podips.svg new file mode 100644 index 00000000000..03f1a44c7d6 --- /dev/null +++ b/stable/_images/podips.svg @@ -0,0 +1,3 @@ + + +
      Service
      ClusterIP
      10.0.0.1
      Servi...
      Service
      ClusterIP
      10.0.0.2
      Servi...
      Service
      ClusterIP
      10.0.0.3
      Servi...
      Pod
      Client
      20.0.0.5
      Pod...
      Kubernetes cluster
      Kubernetes cluster
      Virtual Machine
      Client
      20.0.0.4
      Virtu...
      PodIP: 20.0.0.1
      PodIP: 20.0.0...
      PodIP: 20.0.0.2
      PodIP: 20.0.0...
      PodIP: 20.0.0.3
      PodIP: 20.0.0...
      VPC
      VPC
      Text is not SVG - cannot display
      \ No newline at end of file diff --git a/stable/_sources/contributing.md.txt b/stable/_sources/contributing.md.txt new file mode 100644 index 00000000000..da5fc078732 --- /dev/null +++ b/stable/_sources/contributing.md.txt @@ -0,0 +1,155 @@ +# Contributing to Scylla Operator + +## Prerequisites + +To develop on scylla-operator, your environment must have the following: + +1. [Go 1.13](https://golang.org/dl/) + * Make sure [GOPATH](https://github.com/golang/go/wiki/SettingGOPATH) is set to `GOPATH=$HOME/go`. +2. [Kustomize v3.1.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/v3.1.0) +3. [kubebuilder v2.3.1](https://github.com/kubernetes-sigs/kubebuilder/releases/tag/v2.3.1) +4. [Docker](https://docs.docker.com/install/) +5. Git client installed +6. Github account + +To install all dependencies (Go, kustomize, kubebuilder, dep), simply run: +```bash +./install-dependencies.sh +``` + +## Initial Setup + +### Create a Fork + +From your browser navigate to [http://github.com/scylladb/scylla-operator](http://github.com/scylladb/scylla-operator) and click the "Fork" button. + +### Clone Your Fork + +Open a console window and do the following: + +```bash +# Create the scylla operator repo path +mkdir -p $GOPATH/src/github.com/scylladb + +# Navigate to the local repo path and clone your fork +cd $GOPATH/src/github.com/scylladb + +# Clone your fork, where is your GitHub account name +git clone https://github.com//scylla-operator.git +``` + +### Add Upstream Remote + +First you will need to add the upstream remote to your local git: +```bash +# Add 'upstream' to the list of remotes +git remote add upstream https://github.com/scylladb/scylla-operator.git + +# Verify the remote was added +git remote -v +``` +Now you should have at least `origin` and `upstream` remotes. You can also add other remotes to collaborate with other contributors. + +## Development + +To add a feature or to make a bug fix, you will need to create a branch in your fork and then submit a pull request (PR) from the branch. + +### Building the project + +You can build the project using the Makefile commands: +* Open the Makefile and change the `IMG` environment variable to a repository you have access to. +* Run `make docker-push` and wait for the image to be built and uploaded in your repo. + +### Create a Branch + +From a console, create a new branch based on your fork and start working on it: + +```bash +# Ensure all your remotes are up to date with the latest +git fetch --all + +# Create a new branch that is based off upstream master. Give it a simple, but descriptive name. +# Generally it will be two to three words separated by dashes and without numbers. +git checkout -b feature-name upstream/master +``` + +Now you are ready to make the changes and commit to your branch. + +### Updating Your Fork + +During the development lifecycle, you will need to keep up-to-date with the latest upstream master. As others on the team push changes, you will need to `rebase` your commits on top of the latest. This avoids unnecessary merge commits and keeps the commit history clean. + +Whenever you need to update your local repository, you never want to merge. You **always** will rebase. Otherwise you will end up with merge commits in the git history. If you have any modified files, you will first have to stash them (`git stash save -u ""`). + +```bash +git fetch --all +git rebase upstream/master +``` + +Rebasing is a very powerful feature of Git. You need to understand how it works or else you will risk losing your work. Read about it in the [Git documentation](https://git-scm.com/docs/git-rebase), it will be well worth it. In a nutshell, rebasing does the following: +- "Unwinds" your local commits. Your local commits are removed temporarily from the history. +- The latest changes from upstream are added to the history +- Your local commits are re-applied one by one +- If there are merge conflicts, you will be prompted to fix them before continuing. Read the output closely. It will tell you how to complete the rebase. +- When done rebasing, you will see all of your commits in the history. + +## Submitting a Pull Request + +Once you have implemented the feature or bug fix in your branch, you will open a PR to the upstream repo. Before opening the PR ensure you have added unit tests, are passing the integration tests, cleaned your commit history, and have rebased on the latest upstream. + +In order to open a pull request (PR) it is required to be up to date with the latest changes upstream. If other commits are pushed upstream before your PR is merged, you will also need to rebase again before it will be merged. + +### Commit History + +To prepare your branch to open a PR, you will need to have the minimal number of logical commits so we can maintain +a clean commit history. Most commonly a PR will include a single commit where all changes are squashed, although +sometimes there will be multiple logical commits. + +```bash +# Inspect your commit history to determine if you need to squash commits +git log + +# Rebase the commits and edit, squash, or even reorder them as you determine will keep the history clean. +# In this example, the last 5 commits will be opened in the git rebase tool. +git rebase -i HEAD~5 +``` + +Once your commit history is clean, ensure you have based on the [latest upstream](#updating-your-fork) before you open the PR. + +### Commit messages + +Please make the first line of your commit message a summary of the change that a user (not a developer) of Operator would like to read, +and prefix it with the most relevant directory of the change followed by a colon. +The changelog gets made by looking at just these first lines so make it good! + +If you have more to say about the commit, then enter a blank line and carry on the description. +Remember to say why the change was needed - the commit itself shows what was changed. + +Writing more is better than less. Comparing the behaviour before the change to that after the change is very useful. +Imagine you are writing to yourself in 12 months time when you've forgotten everything about what you just did, and you need to get up to speed quickly. + +If the change fixes an issue then write Fixes #1234 in the commit message. +This can be on the subject line if it will fit. If you don't want to close the associated issue just put #1234 and the change will get linked into the issue. + +Here is an example of a short commit message: + +``` +sidecar: log on reconcile loop - fixes #1234 +``` + +And here is an example of a longer one: +``` + +api: now supports host networking (#1234) + +The operator CRD now has a "network" property that can be used to +select host networking as well as setting the apropriate DNS policy. + +Fixes #1234 +``` + +### Submitting + +Go to the [Scylla Operator github](https://www.github.com/scylladb/scylla-operator) to open the PR. If you have pushed recently, you should see an obvious link to open the PR. If you have not pushed recently, go to the Pull Request tab and select your fork and branch for the PR. + +After the PR is open, you can make changes simply by pushing new commits. Your PR will track the changes in your fork and update automatically. diff --git a/stable/_sources/eks.md.txt b/stable/_sources/eks.md.txt new file mode 100644 index 00000000000..8f8c6b931d3 --- /dev/null +++ b/stable/_sources/eks.md.txt @@ -0,0 +1,129 @@ +# Deploying Scylla on EKS + +This guide is focused on deploying Scylla on EKS with improved performance. +Performance tricks used by the script won't work with different machine tiers. +It sets up the kubelets on EKS nodes to run with [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and uses [local sdd disks](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ssd-instance-store.html) in RAID0 for maximum performance. + +Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the [general guide](generic.md). + +## TL;DR; + +If you don't want to run the commands step-by-step, you can just run a script that will set everything up for you: +```bash +# Edit according to your preference +EKS_REGION=us-east-1 +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c + +# From inside the examples/eks folder +cd examples/eks +./eks.sh -z "$EKS_ZONES" -r "$EKS_REGION" +``` + +After you deploy, see how you can [benchmark your cluster with cassandra-stress](generic.md#benchmark-with-cassandra-stress). + +## Walkthrough + +### EKS Setup + +#### Configure environment variables + +First of all, we export all the configuration options as environment variables. +Edit according to your own environment. + +``` +EKS_REGION=us-east-1 +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c +CLUSTER_NAME=scylla-demo +``` + +#### Creating an EKS cluster + +For this guide, we'll create an EKS cluster with the following: + +* A NodeGroup of 3 `i3-2xlarge` Nodes, where the Scylla Pods will be deployed. These nodes will only accept pods having `scylla-clusters` toleration. + +``` + - name: scylla-pool + instanceType: i3.2xlarge + desiredCapacity: 3 + labels: + scylla.scylladb.com/node-type: scylla + taints: + role: "scylla-clusters:NoSchedule" + ssh: + allow: true + kubeletExtraConfig: + cpuManagerPolicy: static +``` + +* A NodeGroup of 4 `c4.2xlarge` Nodes to deploy `cassandra-stress` later on. These nodes will only accept pods having `cassandra-stress` toleration. + +``` + - name: cassandra-stress-pool + instanceType: c4.2xlarge + desiredCapacity: 4 + labels: + pool: "cassandra-stress-pool" + taints: + role: "cassandra-stress:NoSchedule" + ssh: + allow: true +``` + +* A NodeGroup of 1 `i3.large` Node, where the monitoring stack and operator will be deployed. +``` + - name: monitoring-pool + instanceType: i3.large + desiredCapacity: 1 + labels: + pool: "monitoring-pool" + ssh: + allow: true +``` + +### Prerequisites + +#### Installing script third party dependencies + +Script requires several dependencies: +- eksctl - See: https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html +- kubectl - See: https://kubernetes.io/docs/tasks/tools/install-kubectl/ + +### Deploying ScyllaDB Operator + +Refer to [Deploying Scylla on a Kubernetes Cluster](generic.md) in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites. + +#### Setting up nodes for ScyllaDB + +ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you'll first need to form a RAID array from those disks. +`NodeConfig` performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in [Performance tuning](performance.md) section of ScyllaDB Operator's documentation. + +Deploy `NodeConfig` to let it take care of the above operations: +``` +kubectl apply --server-side -f examples/eks/nodeconfig-alpha.yaml +``` + +#### Deploying Local Volume Provisioner + +Afterwards, deploy ScyllaDB's [Local Volume Provisioner](https://github.com/scylladb/k8s-local-volume-provisioner), capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays. +``` +kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/ +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml +``` + +### Deploying ScyllaDB + +Now you can follow the steps described in [Deploying Scylla on a Kubernetes Cluster](generic.md) to launch your ScyllaDB cluster in a highly performant environment. + +#### Accessing the database + +Instructions on how to access the database can also be found in the [generic guide](generic.md). + +### Deleting an EKS cluster + +Once you are done with your experiments delete your cluster using the following command: + +``` +eksctl delete cluster "${CLUSTER_NAME}" +``` diff --git a/stable/_sources/exposing.md.txt b/stable/_sources/exposing.md.txt new file mode 100644 index 00000000000..348bc4c233d --- /dev/null +++ b/stable/_sources/exposing.md.txt @@ -0,0 +1,300 @@ +# Exposing ScyllaCluster + +This document explains how ScyllaDB Operator exposes ScyllaClusters in different network setups. +A ScyllaCluster can be exposed in various network configurations, independently to clients and nodes. + +:::{note} +ScyllaClusters can be only exposed when the ScyllaDB version used version is `>=2023.1` ScyllaDB Enterprise or `>=5.2` ScyllaDB Open Source. +::: + +## Expose Options + +`exposeOptions` specifies configuration options for exposing ScyllaCluster's. +A ScyllaCluster created without any `exposeOptions` is equivalent to the following: + +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: ClusterIP + broadcastOptions: + clients: + type: ServiceClusterIP + nodes: + type: ServiceClusterIP +``` + +The following sections cover what every field controls and what the configuration options are. + +### Node Service Template + +`nodeService` serves as a template for a node-dedicated Service managed by the Scylla Operator for each node within a ScyllaCluster. +The properties of the Services depend on the selected type. +Additionally, there's an option to define custom annotations, incorporated into each node's Service, +which might be useful for further tweaking the Service properties or related objects. + +#### Headless Type + +For `Headless` type, Scylla Operator creates a Headless Service with a selector pointing to the particular node in the ScyllaCluster. +Such Service doesn't provide any additional IP addresses, and the internal DNS record resolves to the PodIP of a node. + +This type of Service is useful when ScyllaCluster nodes broadcast PodIPs to clients and other nodes. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: Headless +``` + +#### ClusterIP Type + +For `ClusterIP` type, Scylla Operator creates a ClusterIP Service backed by a specific node in the ScyllaCluster. + +These IP addresses are only routable within the same Kubernetes cluster, so it's a good fit, if you don't want to expose them to other networks. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: ClusterIP +``` + +#### LoadBalancer Type + +For the `LoadBalancer` type, Scylla Operator generates a LoadBalancer Service that directs traffic to a specific node within the ScyllaCluster. +On platforms with support for external load balancers, this Service provisions one. +The accessibility of this load balancer's address depends on the platform and any customizations made; in some cases it may be reachable from the internal network or public Internet. + +Customizations are usually managed via Service annotations, key-value pairs provided in `annotations` field are merged into each Service object. +LoadBalancer Services should be configured to pass through entire traffic. +For example, to expose LoadBalancer only to internal network use the following annotations: + +::::{tab-set} +:::{tab-item} EKS +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: LoadBalancer + annotations: + service.beta.kubernetes.io/aws-load-balancer-scheme: internal + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp +``` +::: +:::{tab-item} GKE +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: LoadBalancer + annotations: + networking.gke.io/load-balancer-type: Internal +``` +::: +:::: + +Check platform-specific documentation regarding LoadBalancer configuration to learn more about available options. + +LoadBalancer Service is a superset of ClusterIP Service, implying that each LoadBalancer Service also contains an allocated ClusterIP. +They can be configured using the following fields, which propagate to every node Service: +* externalTrafficPolicy +* internalTrafficPolicy +* loadBalancerClass +* allocateLoadBalancerNodePorts + +Check [Kubernetes Service documentation](https://kubernetes.io/docs/concepts/services-networking/service) to learn more about these options. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: LoadBalancer + loadBalancerClass: my-custom-load-balancer-class +``` + +--- + +### Broadcast Options + +Broadcast options control what is the source of the address being broadcasted to clients and nodes. +It's configured independently for clients and nodes because you may want to expose these two types of traffic on different networks. +Using different networks can help manage costs, reliability, latency, security policies or other metrics you care about. + +#### PodIP Type + +Address broadcasted to clients/nodes is taken from Pod. +By default, the address is taken from Pod's `status.PodIP` field. +Because a Pod can use multiple address, you may want to provide source options by specifying `podIP.source`. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + broadcastOptions: + clients: + type: PodIP + podIP: + source: Status +``` + +#### ServiceClusterIP Type + +Address broadcasted to clients or nodes is taken from `spec.ClusterIP` field of a node's dedicated Service. + +In order to configure it, the `nodeService` template must specify a Service having a ClusterIP assigned. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + broadcastOptions: + clients: + type: ServiceClusterIP +``` + +#### ServiceLoadBalancerIngress Type + +Address broadcasted to clients/nodes is taken from the node dedicated Service, from `status.ingress[0].ipAddress` or `status.ingress[0].hostname` field. + +In order to configure it, the `nodeService` template must specify the LoadBalancer Service. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + broadcastOptions: + clients: + type: ServiceLoadBalancerIngress + podIP: + source: Status +``` + +## Deployment Examples + +The following section contains several specific examples of various network scenarios and explains how nodes and clients communicate with one another. +### In-cluster only + +ScyllaCluster definition: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: ClusterIP + broadcastOptions: + clients: + type: ServiceClusterIP + nodes: + type: ServiceClusterIP +``` + +Both client and nodes are deployed within the same Kubernetes cluster. +They talk through ClusterIP addresses taken from the Service. +Because ClusterIP Services are only routable within the same Kubernetes cluster, this cluster won't be reachable from outside. + +![ClusterIPs](static/exposing/clusterip.svg) + +### In-cluster node-to-node, VPC clients-to-nodes + +ScyllaCluster definition: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: ClusterIP + broadcastOptions: + clients: + type: PodIP + nodes: + type: ServiceClusterIP +``` + +In this scenario, we assume that the Pod IP subnet is routable within a VPC. +Clients within the VPC network can communicate directly with ScyllaCluster nodes using PodIPs. +Nodes communicate with each other exclusively within the same Kubernetes cluster. + +![PodIPs](static/exposing/podips.svg) + +### Multi VPC + +ScyllaCluster definition: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: Headless + broadcastOptions: + clients: + type: PodIP + nodes: + type: PodIP +``` + +In this scenario, we set up two separate Kubernetes clusters in distinct VPCs. +These VPCs are interconnected to facilitate inter-VPC connectivity. +We operate on the assumption that the Pod IP subnet is routable within each VPC. + +Both ScyllaClusters use the same `exposeOptions`, nodes broadcast their Pod IP addresses, enabling them to establish connections with one another. +****Check other documentation pages to know how to connect two ScyllaClusters into one logical cluster. + +Clients, whether deployed within the same Kubernetes cluster or within a VPC, have the capability to reach nodes using their Pod IPs. +Since there is no requirement for any address other than the Pod IP, the `Headless` service type is sufficient. + +![MultiVPC](static/exposing/multivpc.svg) + +### Internet + +ScyllaCluster definition: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: LoadBalancer + broadcastOptions: + clients: + type: ServiceLoadBalancerIngress + nodes: + type: ClusterIP +``` + +We assume that a Kubernetes cluster has been deployed in a cloud provider environment that supports external load balancers. +By specifying the LoadBalancer type in the nodeService template, the Scylla Operator generates a dedicated LB Service for each node. +The cloud provider then establishes an external load balancer with an internet-accessible address. +ScyllaDB nodes broadcast this external address to clients, enabling drivers to connect and discover other nodes. +Since all ScyllaDB nodes reside within the same Kubernetes cluster, there is no need to route traffic through the internet. +Consequently, the nodes are configured to communicate via ClusterIP, which is also accessible within LoadBalancer Services. + +![Internet](static/exposing/loadbalancer.svg) + +--- + +Other more complex scenarios can be built upon these simple ones. diff --git a/stable/_sources/generic.md.txt b/stable/_sources/generic.md.txt new file mode 100644 index 00000000000..d2b26fd16fd --- /dev/null +++ b/stable/_sources/generic.md.txt @@ -0,0 +1,386 @@ +# Deploying Scylla on a Kubernetes Cluster + +This is a guide to deploy a Scylla Cluster in a generic Kubernetes environment, meaning that Scylla will not be deployed with the ideal performance. +Scylla performs the best when it has fast disks and direct access to the cpu. +This requires some extra setup, which is platform-specific. +For specific configuration and setup, check for details about your particular environment: + +* [GKE](gke.md) + +## Prerequisites + +* A Kubernetes cluster +* A [Storage Class](https://kubernetes.io/docs/concepts/storage/storage-classes/) to provision [PersistentVolumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/). +* Helm 3 installed, Go to the [helm docs](https://docs.helm.sh/using_helm/#installing-helm) if you need to install it. + Make sure that you enable the [stable repository](https://github.com/helm/charts#how-do-i-enable-the-stable-repository-for-helm-3) + +## Running locally + +Running kubernetes locally is a daunting and error prone task. +Fortunately there are ways to make life easier and [Minikube](https://minikube.sigs.k8s.io/docs/) makes it a breeze. + +We need to give minikube a little bit more resources than default so start minikube like this: +```console +minikube start --cpus=6 +``` + +Then make kubectl aware of this local installation like this: +```console +eval $(minikube docker-env) +``` + +## Download Scylla Operator +In this guide you will be using the examples and manifests from [Scylla Operator repository](https://github.com/scylladb/scylla-operator), so start off by cloning it to your local machine. +```console +git clone git@github.com:scylladb/scylla-operator.git +cd scylla-operator +``` + +## Deploy Cert Manager +First deploy Cert Manager, you can either follow [upsteam instructions](https://cert-manager.io/docs/installation/kubernetes/) or use following command: + +```console +kubectl apply -f examples/common/cert-manager.yaml +``` +This will install Cert Manager to provision a self-signed certificate. + +Once it's deployed, wait until Cert Manager is ready: + +```console +kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io +kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook +``` + +## Deploy Scylla Operator + +Deploy the Scylla Operator using the following commands: + +```console +kubectl apply -f examples/common/operator.yaml +``` + +This will install the operator in namespace `scylla-operator`. +Wait until it's ready: + +```console +kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator +``` + +If you want to check the logs of the operator you can do so with: + + ```console +kubectl -n scylla-operator logs deployment.apps/scylla-operator +``` + +## Create and Initialize a Scylla Cluster + +Now that the operator is running, we can create an instance of a Scylla cluster by creating an instance of the `clusters.scylla.scylladb.com` resource. +Some of that resource's values are configurable, so feel free to browse `cluster.yaml` and tweak the settings to your liking. +Full details for all the configuration options can be found in the [Scylla Cluster CRD documentation](scylla-cluster-crd.md). + +When you are ready to create a Scylla cluster, simply run: + +```console +kubectl create -f examples/generic/cluster.yaml +``` + +We can verify that a Kubernetes object has been created that represents our new Scylla cluster with the command below. +This is important because it shows that has successfully extended Kubernetes to make Scylla clusters a first class citizen in the Kubernetes cloud-native environment. + +```console +kubectl -n scylla get ScyllaCluster +``` + +Checking the pods that are created is as easy as: + +```console +kubectl -n scylla get pods +``` + +The output should be something like: + +```console +NAME READY STATUS RESTARTS AGE +simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 9m49s +simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 7m43s +simple-cluster-us-east-1-us-east-1a-2 2/2 Running 0 6m46s +``` + +It is important to note that the operator creates these instances according to a pattern. +This pattern is as follows: `CLUSTER_NAME-DATACENTER_NAME-RACK_NAME-INSTANCE_NUMBER` as specified in `cluster.yaml`. + +In the above example we have the following properties: + + - CLUSTER_NAME: `simple-cluster` + - DATACENTER_NAME: `us-east-1` + - RACK_NAME: `us-east-1a` + - INSTANCE_NUMBER: An automatically generated number attached to the pod name. + +We picked the names to resemble something you can find in a cloud service but this is inconsequential, they can be set to anything you want. + +To check if all the desired members are running, you should see the same number of entries from the following command as the number of members that was specified in `cluster.yaml`: + +```console +kubectl -n scylla get pod -l app=scylla +``` + +You can also track the state of a Scylla cluster from its status. To check the current status of a Cluster, run: + +```console +kubectl -n scylla describe ScyllaCluster simple-cluster +``` + +Checking the logs of the running scylla instances can be done like this: + +```console +kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 scylla +``` + +### Configure host networking + +To squeeze the most out of your deployment it is sometimes necessary to employ [host networking](https://kubernetes.io/docs/concepts/services-networking/). +To enable this the CRD allows for specifying a `network` parameter as such: + +```yaml +version: 4.0.0 + agentVersion: 2.0.2 + cpuset: true + network: + hostNetworking: true +``` + +This will result in hosts network to be used for the Scylla Stateful Set deployment. + +### Configure container kernel parameters + +Sometimes it is necessary to run the container with different kernel parameters. +In order to support this, the Scylla Operator defines a cluster property `sysctls` that is a list of the desired key-value pairs to set. + +___For example___: To increase the number events available for asynchronous IO processing in the Linux kernel to N set sysctls to`fs.aio-max-nr=N`. + +```yaml +spec: + sysctls: + - "fs.aio-max-nr=2097152" +``` + +### Deploying Alternator + +The operator is also capable of deploying [Alternator](https://www.scylladb.com/alternator/) instead of the regular Scylla. +This requires a small change in the cluster definition. +Change the `cluster.yaml` file from this: +```yaml +spec: + version: 4.0.0 + agentVersion: 2.0.2 + developerMode: true + datacenter: + name: us-east-1 +``` +to this: +```yaml +spec: + version: 4.0.0 + alternator: + port: 8000 + writeIsolation: only_rmw_uses_lwt + agentVersion: 2.0.2 + developerMode: true + datacenter: + name: us-east-1 +``` +You can specify whichever port you want. + +You must provide desired write isolation, supported values are: "always", "forbid_rmw", "only_rmw_uses_lwt". +Difference between those isolation levels can be found in Scylla Alternator documentation. + +Once this is done the regular CQL ports will no longer be available, the cluster is a pure Alternator cluster. + +## Accessing the Database + +* From kubectl: + +To get a cqlsh shell in your new Cluster: +```console +kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- cqlsh +> DESCRIBE KEYSPACES; +``` + + +* From inside a Pod: + +When you create a new Cluster, automatically creates a Service for the clients to use in order to access the Cluster. +The service's name follows the convention `-client`. +You can see this Service in your cluster by running: +```console +kubectl -n scylla describe service simple-cluster-client +``` +Pods running inside the Kubernetes cluster can use this Service to connect to Scylla. +Here's an example using the [Python Driver](https://github.com/datastax/python-driver): +```python +from cassandra.cluster import Cluster + +cluster = Cluster(['simple-cluster-client.scylla.svc']) +session = cluster.connect() +``` + +If you are running the Alternator you can access the API on the port you specified using plain http. + +## Configure Scylla + +The operator can take a ConfigMap and apply it to the scylla.yaml configuration file. +This is done by adding a ConfigMap to Kubernetes and refering to this in the Rack specification. +The ConfigMap is just a file called `scylla.yaml` that has the properties you want to change in it. +The operator will take the default properties for the rest of the configuration. + +* Create a ConfigMap the default name that the operator uses is `scylla-config`: +```console +kubectl create configmap scylla-config -n scylla --from-file=/path/to/scylla.yaml +``` +* Wait for the mount to propagate and then restart the cluster: +```console +kubectl rollout restart -n scylla statefulset/simple-cluster-us-east-1-us-east-1a +``` +* The new config should be applied automatically by the operator, check the logs to be sure. + +Configuring `cassandra-rackdc.properties` is done by adding the file to the same mount as `scylla.yaml`. +```console +kubectl create configmap scylla-config -n scylla --from-file=/tmp/scylla.yaml --from-file=/tmp/cassandra-rackdc.properties -o yaml --dry-run | kubectl replace -f - +``` +The operator will then apply the overridable properties `prefer_local` and `dc_suffix` if they are available in the provided mounted file. + +:::{note} +If you want to enable authentication, you first need to adjust `system_auth` keyspace replication factor to the number of nodes in the datacenter via cqlsh. It allows you to ensure that the user’s information is kept highly available for the cluster. If `system_auth` is not equal to the number of nodes and a node fails, the user whose information is on that node will be denied access. +For production environments only use `NetworkTopologyStrategy`. + +```shell +kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : };" +``` + +You can read more about enabling authentication in the [Enable authentication](https://opensource.docs.scylladb.com/stable/operating-scylla/security/authentication.html) section of ScyllaDB's documentation. +::: + +## Configure Scylla Manager Agent + +The operator creates a second container for each scylla instance that runs [Scylla Manager Agent](https://hub.docker.com/r/scylladb/scylla-manager-agent). +This container serves as a sidecar and it's the main endpoint for interacting with Scylla API. +The Scylla Manager Agent can be configured with various things such as the security token used to allow access to Scylla API and storage providers for backups. + +To configure the agent you just create a new secret called _scylla-agent-config-secret_ and populate it with the contents in the `scylla-manager-agent.yaml` file like this: +```console +kubectl create secret -n scylla generic scylla-agent-config-secret --from-file scylla-manager-agent.yaml +``` + +See [Scylla Manager Agent configuration](https://manager.docs.scylladb.com/stable/config/scylla-manager-config.html) for a complete reference of the Scylla Manager agent config file. + +### Scylla Manager Agent auth token + +Operator provisions Agent auth token by copying value from user provided config secret or auto generates it if it's empty. +To check which value is being used, decode content of `-auth-token` secret. +To change it simply remove the secret. Operator will create a new one. To pick up the change in the cluster, initiate a rolling restart. + +## Set up monitoring + +To set up monitoring using Prometheus and Grafana follow [this guide](monitoring.md). + +## Scale a ScyllaCluster + +The operator supports adding new nodes to existing racks, adding new racks to the cluster, as well as removing both single nodes and entire racks. To introduce the changes, edit the cluster with: +```console +kubectl -n scylla edit scyllaclusters.scylla.scylladb.com/simple-cluster +``` +* To modify the number of nodes in a rack, update the `members` field of the selected rack to a desired value. +* To add a new rack, append it to the `.spec.datacenter.racks` list. Remember to choose a unique rack name for the new rack. +* To remove a rack, first scale it down to zero nodes, and then remove it from `.spec.datacenter.racks` list. + +Having edited and saved the yaml, you can check your cluster's Status and Events to retrieve information about what's happening: +```console +kubectl -n scylla describe scyllaclusters.scylla.scylladb.com/simple-cluster +``` + +:::{note} +If you have configured ScyllaDB with `authenticator` set to `PasswordAuthenticator`, you need to manually configure the replication factor of the `system_auth` keyspace with every scaling operation. + +```shell +kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -u -p -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : };" +``` + +It is recommended to set `system_auth` replication factor to the number of nodes in each datacenter. +::: + +## Benchmark with cassandra-stress + +After deploying our cluster along with the monitoring, we can benchmark it using cassandra-stress and see its performance in Grafana. We have a mini cli that generates Kubernetes Jobs that run cassandra-stress against a cluster. + +> Because cassandra-stress doesn't scale well to multiple cores, we use multiple jobs with a small core count for each + +```bash + +# Run a benchmark with 10 jobs, with 6 cpus and 50.000.000 operations each. +# Each Job will throttle throughput to 30.000 ops/sec for a total of 300.000 ops/sec. +hack/cass-stress-gen.py --num-jobs=10 --cpu=6 --memory=20G --ops=50000000 --limit=30000 +kubectl apply -f scripts/cassandra-stress.yaml +``` + +Make sure you set the proper arguments in case you have altered things such as _name_ or _namespace_. + +```bash +./hack/cass-stress-gen.py -h +usage: cass-stress-gen.py [-h] [--num-jobs NUM_JOBS] [--name NAME] [--namespace NAMESPACE] [--scylla-version SCYLLA_VERSION] [--host HOST] [--cpu CPU] [--memory MEMORY] [--ops OPS] [--threads THREADS] [--limit LIMIT] + [--connections-per-host CONNECTIONS_PER_HOST] [--print-to-stdout] [--nodeselector NODESELECTOR] + +Generate cassandra-stress job templates for Kubernetes. + +optional arguments: + -h, --help show this help message and exit + --num-jobs NUM_JOBS number of Kubernetes jobs to generate - defaults to 1 + --name NAME name of the generated yaml file - defaults to cassandra-stress + --namespace NAMESPACE + namespace of the cassandra-stress jobs - defaults to "default" + --scylla-version SCYLLA_VERSION + version of scylla server to use for cassandra-stress - defaults to 4.0.0 + --host HOST ip or dns name of host to connect to - defaults to scylla-cluster-client.scylla.svc + --cpu CPU number of cpus that will be used for each job - defaults to 1 + --memory MEMORY memory that will be used for each job in GB, ie 2G - defaults to 2G * cpu + --ops OPS number of operations for each job - defaults to 10000000 + --threads THREADS number of threads used for each job - defaults to 50 * cpu + --limit LIMIT rate limit for each job - defaults to no rate-limiting + --connections-per-host CONNECTIONS_PER_HOST + number of connections per host - defaults to number of cpus + --print-to-stdout print to stdout instead of writing to a file + --nodeselector NODESELECTOR + nodeselector limits cassandra-stress pods to certain nodes. Use as a label selector, eg. --nodeselector role=scylla +``` +While the benchmark is running, open up Grafana and take a look at the monitoring metrics. + +After the Jobs finish, clean them up with: +```bash +kubectl delete -f scripts/cassandra-stress.yaml +``` + +## Clean Up + +To clean up all resources associated with this walk-through, you can run the commands below. + +**NOTE:** this will destroy your database and delete all of its associated data. + +```console +kubectl delete -f examples/generic/cluster.yaml +kubectl delete -f examples/common/operator.yaml +kubectl delete -f examples/common/cert-manager.yaml +``` + +## Troubleshooting + +If the cluster does not come up, the first step would be to examine the operator's logs: + +```console +kubectl -n scylla-operator logs deployment.apps/scylla-operator +``` + +If everything looks OK in the operator logs, you can also look in the logs for one of the Scylla instances: + +```console +kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 +``` diff --git a/stable/_sources/gke.md.txt b/stable/_sources/gke.md.txt new file mode 100644 index 00000000000..cfad6709a17 --- /dev/null +++ b/stable/_sources/gke.md.txt @@ -0,0 +1,173 @@ +# Deploying Scylla on GKE + +This guide is focused on deploying Scylla on GKE with maximum performance (without any persistence guarantees). +It sets up the kubelets on GKE nodes to run with [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and uses [local sdd disks](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/local-ssd) in RAID0 for maximum performance. + +Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the [general guide](generic.md). + +## TL;DR; + +If you don't want to run the commands step-by-step, you can just run a script that will set everything up for you: +```bash +# Edit according to your preference +GCP_USER=$(gcloud config list account --format "value(core.account)") +GCP_PROJECT=$(gcloud config list project --format "value(core.project)") +GCP_ZONE=us-west1-b + +# From inside the examples/gke folder +cd examples/gke +./gke.sh -u "$GCP_USER" -p "$GCP_PROJECT" -z "$GCP_ZONE" + +# Example: +# ./gke.sh -u yanniszark@arrikto.com -p gke-demo-226716 -z us-west1-b +``` + +:::{warning} +Make sure to pass a ZONE (ex.: us-west1-b) and not a REGION (ex.: us-west1) or it will deploy nodes in each ZONE available in the region. +::: + +After you deploy, see how you can [benchmark your cluster with cassandra-stress](generic.md#benchmark-with-cassandra-stress). + +## Walkthrough + +### Google Kubernetes Engine Setup + +#### Configure environment variables + +First of all, we export all the configuration options as environment variables. +Edit according to your own environment. + +``` +GCP_USER=$( gcloud config list account --format "value(core.account)" ) +GCP_PROJECT=$( gcloud config list project --format "value(core.project)" ) +GCP_REGION=us-west1 +GCP_ZONE=us-west1-b +CLUSTER_NAME=scylla-demo +CLUSTER_VERSION=$( gcloud container get-server-config --zone ${GCP_ZONE} --format "value(validMasterVersions[0])" ) +``` + +#### Creating a GKE cluster + +First we need to change kubelet CPU Manager policy to static by providing a config file. Create file called `systemconfig.yaml` with the following content: +``` +kubeletConfig: + cpuManagerPolicy: static +``` + +Then we'll create a GKE cluster with the following: + +1. A NodePool of 2 `n1-standard-8` Nodes, where the operator and the monitoring stack will be deployed. These are generic Nodes and their free capacity can be used for other purposes. + ``` + gcloud container \ + clusters create "${CLUSTER_NAME}" \ + --cluster-version "${CLUSTER_VERSION}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-8" \ + --num-nodes "2" \ + --disk-type "pd-ssd" --disk-size "20" \ + --image-type "UBUNTU_CONTAINERD" \ + --system-config-from-file=systemconfig.yaml \ + --enable-stackdriver-kubernetes \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +2. A NodePool of 2 `n1-standard-32` Nodes to deploy `cassandra-stress` later on. + + ``` + gcloud container --project "${GCP_PROJECT}" \ + node-pools create "cassandra-stress-pool" \ + --cluster "${CLUSTER_NAME}" \ + --zone "${GCP_ZONE}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-32" \ + --num-nodes "2" \ + --disk-type "pd-ssd" --disk-size "20" \ + --node-taints role=cassandra-stress:NoSchedule \ + --image-type "UBUNTU_CONTAINERD" \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +3. A NodePool of 4 `n1-standard-32` Nodes, where the Scylla Pods will be deployed. Each of these Nodes has 8 local NVMe SSDs attached, which are provided as [raw block devices](https://cloud.google.com/kubernetes-engine/docs/concepts/local-ssd#block). It is important to disable `autoupgrade` and `autorepair`. Automatic cluster upgrade or node repair has a hard timeout after which it no longer respect PDBs and force deletes the Compute Engine instances, which also deletes all data on the local SSDs. At this point, it's better to handle upgrades manually, with more control over the process and error handling. + ``` + gcloud container \ + node-pools create "scylla-pool" \ + --cluster "${CLUSTER_NAME}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-32" \ + --num-nodes "4" \ + --disk-type "pd-ssd" --disk-size "20" \ + --local-nvme-ssd-block count="8" \ + --node-taints role=scylla-clusters:NoSchedule \ + --node-labels scylla.scylladb.com/node-type=scylla \ + --image-type "UBUNTU_CONTAINERD" \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +#### Setting Yourself as `cluster-admin` +> (By default GKE doesn't give you the necessary RBAC permissions) + +Get the credentials for your new cluster +``` +gcloud container clusters get-credentials "${CLUSTER_NAME}" --zone="${GCP_ZONE}" +``` + +Create a ClusterRoleBinding for your user. +In order for this to work you need to have at least permission `container.clusterRoleBindings.create`. +The easiest way to obtain this permission is to enable the `Kubernetes Engine Admin` role for your user in the GCP IAM web interface. +``` +kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user "${GCP_USER}" +``` + + +### Prerequisites + +### Deploying ScyllaDB Operator + +Refer to [Deploying Scylla on a Kubernetes Cluster](generic.md) in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites. + +#### Setting up nodes for ScyllaDB + +ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you'll first need to form a RAID array from those disks. +`NodeConfig` performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in [Performance tuning](performance.md) section of ScyllaDB Operator's documentation. + +Deploy `NodeConfig` to let it take care of the above operations: +``` +kubectl apply --server-side -f examples/gke/nodeconfig-alpha.yaml +``` + +#### Deploying Local Volume Provisioner + +Afterwards, deploy ScyllaDB's [Local Volume Provisioner](https://github.com/scylladb/k8s-local-volume-provisioner), capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays. +``` +kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/ +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml +``` + +### Deploy Scylla cluster +In order for the example to work you need to modify the cluster definition in the following way: + +``` +sed -i "s//${GCP_REGION}/g;s//${GCP_ZONE}/g" examples/gke/cluster.yaml +``` + +This will inject your region and zone into the cluster definition so that it matches the kubernetes cluster you just created. + +### Deploying ScyllaDB + +Now you can follow the steps described in [Deploying Scylla on a Kubernetes Cluster](generic.md) to launch your ScyllaDB cluster in a highly performant environment. + +#### Accessing the database + +Instructions on how to access the database can also be found in the [generic guide](generic.md). + +### Deleting a GKE cluster + +Once you are done with your experiments delete your cluster using the following command: + +``` +gcloud container --project "${GCP_PROJECT}" clusters delete --zone "${GCP_ZONE}" "${CLUSTER_NAME}" +``` diff --git a/stable/_sources/helm.md.txt b/stable/_sources/helm.md.txt new file mode 100644 index 00000000000..56fbe9620ac --- /dev/null +++ b/stable/_sources/helm.md.txt @@ -0,0 +1,339 @@ +# Deploying Scylla stack using Helm Charts + +In this example we will install Scylla stack on Kubernetes. This includes the following components: +- Scylla Operator +- Scylla Manager +- Scylla + +We will use Minikube K8s cluster, but this could be any K8s cluster supported by the Scylla Operator. + +### Prerequisites + +- Kubernetes 1.16+ +- Helm 3+ + +### TL;DR + +``` +helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable +helm repo update +kubectl apply -f examples/common/cert-manager.yaml +helm install scylla-operator scylla/scylla-operator --create-namespace --namespace scylla-operator +helm install scylla-manager scylla/scylla-manager --create-namespace --namespace scylla-manager +helm install scylla scylla/scylla --create-namespace --namespace scylla +``` + +### Deploy Cert Manager + +This step is optional if you want to use your own certificate. +If you don't have one, make sure to not disable autogeneration using Scylla Operator Helm Chart. + +First deploy Cert Manager, you can either follow [upsteam instructions](https://cert-manager.io/docs/installation/kubernetes/) or use following command: + +```console +kubectl apply -f examples/common/cert-manager.yaml +``` + +Once it's deployed, wait until all Cert Manager pods will enter into Running state: + +```console +kubectl wait -n cert-manager --for=condition=ready pod -l app=cert-manager --timeout=60s +``` + +### Helm Chart repository + +To install Scylla Helm Chart repository execute the following commands: +``` +helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable +helm repo update +``` + +Then you can search through repository, it should contain at least three Helm charts: +``` +helm search repo scylla +NAME CHART VERSION APP VERSION DESCRIPTION +scylla/scylla 1.0.1 v1.0.1 Scylla is a close-to-the-hardware rewrite of Ca... +scylla/scylla-manager 1.0.1 v1.0.1 Scylla Manager automates database operations. +scylla/scylla-operator 1.0.1 v1.0.1 Scylla Operator is a Kubernetes Operator for ma... +``` + +All these charts should be installable without any need of customizing (defaults are provided). +Although Helm is used for this particular reason, so lets customize them a bit. + +### Scylla Operator Chart + +This chart is very simple, most interesting customizable fields are `image`, `resources` and `webhook`. +All others can be looked up in Chart source in Scylla Operator repository. + +#### image + +Image allows to define which Scylla Operator image will be used. By default it downloads the image from main +Docker Hub repository, using version defined in Helm Chart. +You can also change `pullPolicy` if default one does not +fullfill your needs. In [Kubernetes documentation](https://kubernetes.io/docs/concepts/containers/images/) you +can read more about different pull policies. + +Image URL will be composed based on these fields in follwing pattern: +`repository/scylla-operator:tag` +```yaml +image: + repository: scylladb + pullPolicy: IfNotPresent + tag: "" +``` + +#### resources + +You can customize how much resources will be allocated for Operator pods via `resource` field: +```yaml +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 32Mi +``` + +To read more about resource specification, follow [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +#### webhook + +Webhook field allows to decide whether you want to use autogenerated self-signed certificate using Cert Manager or +whether you want to provide your own certificate. + +`createSelfSignedCertificate` specifies whether a self-signed certificate should be created using Cert Manager +`certificateSecretName`: name of a secret containing custom certificate. + +```yaml +webhook: + createSelfSignedCertificate: true + certificateSecretName: "" +``` + +#### Customization + +You can customize all these fields and others by providing file containing desired values. +Content of this file will overwrite default values. + +You can find an example in Scylla Operator repository under `examples/helm/values.operator.yaml` + +#### Installation + +To deploy Scylla Operator using customized values file execute the following: +``` +helm install scylla-operator scylla/scylla-operator --values examples/helm/values.operator.yaml --create-namespace --namespace scylla-operator +``` + +### Scylla Helm Chart + +Scylla Chart allows to customize and deploy Scylla cluster. +By default Scylla Helm charts deploys working Scylla cluster, but of course we can customize it. + +#### Customization + +Versions of images used in the cluster can be set via `scyllaImage` and `agentImage` +```yaml +scyllaImage: + repository: scylladb/scylla + tag: 4.3.0 + +agentImage: + repository: scylladb/scylla-manager-agent + tag: 2.2.1 +``` + +A minimal Scylla cluster can be expressed as: +```yaml +datacenter: us-east-1 +racks: +- name: us-east-1b + members: 2 + storage: + capacity: 5G + resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 1 + memory: 1Gi +``` + +Above cluster will use 4.3.0 Scylla, 2.2.1 Scylla Manager Agent sidecar and will have a single rack having 2 nodes. +Each node will have a single CPU and 1 GiB of memory. + +For other customizable fields, please refer to [ScyllaCluster CRD definition](scylla-cluster-crd.md). +CRD Rack Spec and Helm Chart Rack should have the same fields. + +#### Installation + +To deploy Scylla cluster using customzied values file execute the following command: +``` +helm install scylla scylla/scylla --values examples/helm/values.cluster.yaml --create-namespace --namespace scylla +``` + +Scylla Operator will provision this cluster on your K8s environment. + +### Scylla Manager Helm Chart + +Scylla Manager Chart allows to customize and deploy Scylla Manager in K8s environment. +Scylla Manager consist of two applications (Scylla Manager itself and Scylla Manager Controller) and additional Scylla cluster. + +To read more about Scylla Manager see [Manager guide](manager.md). + +#### Scylla Manager + +To set version of used Scylla Manager you can use `image` field: +```yaml +image: + repository: scylladb + pullPolicy: IfNotPresent + tag: 2.2.1 +``` +To control how many resources are allocated for Scylla Manager use `resource` field: +```yaml +resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 500m + memory: 500Mi +``` + +#### Scylla Manager Controller + +Similarly Scylla Manager Controller image can be customized: + +```yaml +controllerImage: + repository: scylladb + pullPolicy: IfNotPresent + tag: "" +``` + +And allocated resources: +```yaml +controllerResources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi +``` + +#### Scylla + +To customize internal Scylla instance dedicated to Scylla Manager, see guide above customizing Scylla Helm Chart. +It's definition should land as a `scylla` field. + +#### Customization + +All others customizable fields can be looked up in Chart source in Scylla Operator repository. + +#### Installation + +To deploy Scylla Manager using customized values file execute the following command: +``` +helm install scylla-manager scylla/scylla-manager --values examples/helm/values.manager.yaml --create-namespace --namespace scylla-manager +``` + +## Results + +Scylla need some time to bootstrap all nodes, but after some time you should be ready to roll. It was simple isn't it? +You can validate if everything was set up correctly by looking at the all resources created in used namespaces. + +Scylla Operator: +```shell +$ kubectl -n scylla-operator get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-operator-5dbcb54f5c-vjm4m 1/1 Running 0 51s +pod/scylla-operator-5dbcb54f5c-wfjbw 1/1 Running 0 51s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-operator-webhook ClusterIP 10.105.207.130 443/TCP 51s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/scylla-operator 2/2 2 2 51s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/scylla-operator-5dbcb54f5c 2 2 2 51s + +``` + +Operator is running! + +Scylla Manager: +```shell +$ kubectl -n scylla-manager get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-manager-669db64dd-bcm4v 1/1 Running 0 89s +pod/scylla-manager-controller-844ccc56c4-drbth 1/1 Running 0 89s +pod/scylla-manager-controller-844ccc56c4-rhwqx 1/1 Running 0 89s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-manager ClusterIP 10.105.231.53 80/TCP,5090/TCP 89s +service/scylla-manager-client ClusterIP None 9180/TCP,5090/TCP 89s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/scylla-manager 1/1 1 1 89s +deployment.apps/scylla-manager-controller 2/2 2 2 89s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/scylla-manager-669db64dd 1 1 1 89s +replicaset.apps/scylla-manager-controller-844ccc56c4 2 2 2 89s + + +``` + +Good to go, ready to serve! + +Scylla itself: +```shell +$ kubectl -n scylla get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-us-east-1-us-east-1b-0 2/2 Running 0 5m58s +pod/scylla-us-east-1-us-east-1b-1 2/2 Running 0 4m29s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-client ClusterIP None 9180/TCP,5090/TCP 5m59s +service/scylla-us-east-1-us-east-1b-0 ClusterIP 10.43.149.92 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 5m58s +service/scylla-us-east-1-us-east-1b-1 ClusterIP 10.43.49.0 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 4m29s + +NAME READY AGE +statefulset.apps/scylla-us-east-1-us-east-1b 2/2 5m59s +``` + +Two running nodes, exactly what we were asking for. + +## Monitoring + +To spin up a Prometheus monitoring refer to [monitoring guide](monitoring.md). + +Helm charts can create ServiceMonitors needed to observe Scylla Managger and Scylla. +Both of these Helm Charts allows to specify whether you want to create a ServiceMonitor: +```yaml +serviceMonitor: + create: false +``` + +Change `create` to `true` and update your current deployment using: +```shell +helm upgrade --install scylla --namespace scylla scylla/scylla -f examples/helm/values.cluster.yaml +``` + +Helm should notice the difference, install the ServiceMonitor, and then Prometheous will be able to scrape metrics. + +## Cleanup + +To remove these applications you can simply uninstall them using Helm CLI: +```shell +helm uninstall scylla -n scylla +helm uninstall scylla-manager -n scylla-manager +helm uninstall scylla-operator -n scylla-operator +``` diff --git a/stable/_sources/index.rst.txt b/stable/_sources/index.rst.txt new file mode 100644 index 00000000000..7891296c2c1 --- /dev/null +++ b/stable/_sources/index.rst.txt @@ -0,0 +1,65 @@ +============================= +Scylla Operator Documentation +============================= + +.. toctree:: + :hidden: + :maxdepth: 1 + + generic + eks + gke + helm + manager + monitoring + migration + nodeoperations/index + exposing + multidc/index + performance + upgrade + releases + support/index + scylla-cluster-crd + contributing + +Scylla Operator is an open source project which helps users of Scylla Open Source and Scylla Enterprise run Scylla on Kubernetes (K8s) +The Scylla operator manages Scylla clusters deployed to Kubernetes and automates tasks related to operating a Scylla cluster, like installation, out and downscale, rolling upgrades. + +.. image:: logo.png + :width: 200pt + +For the latest status of the project, and reports issue, see the Github Project. Also check out the K8s Operator lesson on Scylla University. + +scylla-operator is a Kubernetes Operator for managing Scylla clusters. + +Currently it supports: + +* Deploying multi-zone clusters +* Scaling up or adding new racks +* Scaling down +* Monitoring with Prometheus and Grafana +* Integration with `Scylla Manager `_ +* Dead node replacement +* Version Upgrade +* Backup +* Repairs +* Autohealing + +**Choose a topic to begin**: + +* :doc:`Deploying Scylla on a Kubernetes Cluster ` +* :doc:`Deploying Scylla on EKS ` +* :doc:`Deploying Scylla on GKE ` +* :doc:`Deploying Scylla Manager on a Kubernetes Cluster ` +* :doc:`Deploying Scylla stack using Helm Charts ` +* :doc:`Setting up Monitoring using Prometheus and Grafana ` +* :doc:`Node operations ` +* :doc:`Exposing ScyllaCluster to other networks ` +* :doc:`Deploying multi-datacenter ScyllaDB clusters in Kubernetes ` +* :doc:`Performance tuning [Experimental] ` +* :doc:`Upgrade procedures ` +* :doc:`Releases ` +* :doc:`Support ` +* :doc:`Scylla Cluster Custom Resource Definition (CRD) ` +* :doc:`Contributing to the Scylla Operator Project ` diff --git a/stable/_sources/manager.md.txt b/stable/_sources/manager.md.txt new file mode 100644 index 00000000000..ce39f6812a5 --- /dev/null +++ b/stable/_sources/manager.md.txt @@ -0,0 +1,258 @@ +# Deploying Scylla Manager on a Kubernetes Cluster + +Scylla Manager is a product for database operations automation, +it can schedule tasks such as repairs and backups. +Scylla Manager can manage multiple Scylla clusters and run cluster-wide tasks +in a controlled and predictable way. + +Scylla Manager is available for Scylla Enterprise customers and Scylla Open Source users. +With Scylla Open Source, Scylla Manager is limited to 5 nodes. +See the Scylla Manager [Proprietary Software License Agreement](https://www.scylladb.com/scylla-manager-software-license-agreement/) for details. + +## Prerequisites + +* Kubernetes cluster +* Scylla Operator - see [generic guide](generic.md) + +## Architecture + +Scylla Manager in K8s consist of: +- Dedicated Scylla Cluster + + Scylla Manager persists its state to a Scylla cluster. +Additional small single node cluster is spawned in the Manager namespace. + +- Scylla Manager Controller + + Main mission of Controller is to watch changes of Scylla Clusters, and synchronize three states. + 1. What user wants - task definition in CRD. + 2. What Controller registered - Task name to Task ID mapping - CRD status. + 3. Scylla Manager task listing - internal state of Scylla Manager. + + When Scylla Cluster CRD is being deployed Controller will register it in Scylla Manager once cluster reaches desired node count. +Once Cluster is fully up and running it will schedule all tasks defined in Cluster CRD. +Controller also supports task updates and unscheduling. + +- Scylla Manager + + Regular Scylla Manager, the same used in cloud and bare metal deployments. + + + +## Deploy Scylla Manager + +Deploy the Scylla Manager using the following commands: + +```console +kubectl apply -f examples/common/manager.yaml +``` + +This will install the Scylla Manager in the `scylla-manager` namespace. +You can check if the Scylla Manager is up and running with: + +```console +kubectl -n scylla-manager get pods +NAME READY STATUS RESTARTS AGE +scylla-manager-cluster-manager-dc-manager-rack-0 2/2 Running 0 37m +scylla-manager-controller-0 1/1 Running 0 28m +scylla-manager-scylla-manager-7bd9f968b9-w25jw 1/1 Running 0 37m +``` + +As you can see there are three pods: +* `scylla-manager-cluster-manager-dc-manager-rack-0` - is a single node Scylla cluster. +* `scylla-manager-controller-0` - Scylla Manager Controller. +* `scylla-manager-scylla-manager-7bd9f968b9-w25jw` - Scylla Manager. + +To see if Scylla Manager is fully up and running we can check their logs. +To do this, execute following command: + + ```console +kubectl -n scylla-manager logs scylla-manager-controller-0 +``` + +The output should be something like: +```console +{"L":"INFO","T":"2020-09-23T11:25:27.882Z","M":"Scylla Manager Controller started","version":"","build_date":"","commit":"","built_by":"","go_version":"","options":{"Name":"scylla-manager-controller-0","Namespace":"scylla-manager","LogLevel":"debug","ApiAddress":"http://127.0.0.1:5080/api/v1"},"_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"} +{"L":"INFO","T":"2020-09-23T11:25:28.435Z","M":"Registering Components.","_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"} +``` + +To check logs of Scylla Manager itself, use following command: +```console +kubectl -n scylla-manager logs scylla-manager-scylla-manager-7bd9f968b9-w25jw +``` + +The output should be something like: + +```console +{"L":"INFO","T":"2020-09-23T11:26:53.238Z","M":"Scylla Manager Server","version":"2.1.2-0.20200816.76cc4dcc","pid":1,"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Using config","config":{"HTTP":"127.0.0.1:5080","HTTPS":"","TLSCertFile":"/var/lib/scylla-manager/scylla_manager.crt","TLSKeyFile":"/var/lib/scylla-manager/scylla_manager.key","TLSCAFile":"","Prometheus":":56090","PrometheusScrapeInterval":5000000000,"debug":"127.0.0.1:56112","Logger":{"Mode":"stderr","Level":"info","Development":false},"Database":{"Hosts":["scylla-manager-cluster-manager-dc-manager-rack-0.scylla-manager.svc"],"SSL":false,"User":"","Password":"","LocalDC":"","Keyspace":"scylla_manager","MigrateDir":"/etc/scylla-manager/cql","MigrateTimeout":30000000000,"MigrateMaxWaitSchemaAgreement":300000000000,"ReplicationFactor":1,"Timeout":600000000,"TokenAware":true},"SSL":{"CertFile":"","Validate":true,"UserCertFile":"","UserKeyFile":""},"Healthcheck":{"Timeout":250000000,"SSLTimeout":750000000},"Backup":{"DiskSpaceFreeMinPercent":10,"AgeMax":43200000000000},"Repair":{"SegmentsPerRepair":1,"ShardParallelMax":0,"ShardFailedSegmentsMax":100,"PollInterval":200000000,"ErrorBackoff":300000000000,"AgeMax":0,"ShardingIgnoreMsbBits":12}},"config_files":["/mnt/etc/scylla-manager/scylla-manager.yaml"],"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Checking database connectivity...","_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +``` + +If there are no errors in the logs, let's spin a Scylla Cluster. + +## Cluster registration + + +When the Scylla Manager is fully up and running, lets create a regular instance of Scylla cluster. + +See [generic tutorial](generic.md) to spawn your cluster. + +Note: If you already have some Scylla Clusters, after installing Manager they should be +automatically registered in Scylla Manager. + +Once cluster reaches desired node count, cluster status will be updated with ID under which it was registered in Manager. + + ```console +kubectl -n scylla describe Cluster + +[...] +Status: + Manager Id: d1d532cd-49f2-4c97-9263-25126532803b + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.0.0 +``` +You can use this ID to talk to Scylla Manager using `sctool` CLI installed in Scylla Manager Pod. +You can also use Cluster name in `namespace/cluster-name` format. + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list + +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b) +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮ +│ Task │ Arguments │ Next run │ Status │ +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤ +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b │ │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE │ +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd │ │ 23 Sep 20 14:29:57 CEST (+1m) │ NEW │ +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯ + +``` + +Scylla Manager by default registers recurring healhcheck tasks for Agent and for each of the enabled frontends (CQL, Alternator). + +In this task listing we can see CQL and REST healthchecks. + +## Task scheduling + +You can either define tasks prior Cluster creation, or for existing Cluster. +Let's edit already running cluster definition to add repair and backup task. +```console +kubectl -n scylla edit Cluster simple-cluster +``` + +Add following task definition to Cluster spec: +``` + repairs: + - name: "users repair" + keyspace: ["users"] + interval: "1d" + backups: + - name: "weekly backup" + location: ["s3:cluster-backups"] + retention: 3 + interval: "7d" + - name: "daily backup" + location: ["s3:cluster-backups"] + retention: 7 + interval: "1d" +``` + +For full task definition configuration consult [Scylla Cluster CRD](scylla-cluster-crd.md). + +**Note**: Scylla Manager Agent must have access to above bucket prior the update in order to schedule backup task. +Consult Scylla Manager documentation for details on how to set it up. + +Scylla Manager Controller will spot this change and will schedule tasks in Scylla Manager. + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list + +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b) +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮ +│ Task │ Arguments │ Next run │ Status │ +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤ +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b │ │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE │ +│ backup/275aae7f-c436-4fc8-bcec-479e65fb8372 │ -L s3:cluster-backups --retention 3 │ 23 Sep 20 14:28:58 CEST (+7d) │ NEW │ +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd │ │ 23 Sep 20 14:29:57 CEST (+1m) │ NEW │ +│ repair/d4946360-c29d-4bb4-8b9d-619ada495c2a │ │ 23 Sep 20 14:38:42 CEST │ NEW │ +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯ + +``` + +As you can see, we have two new tasks, weekly recurring backup, and one repair which should start shortly. + +To check progress of run you can use following command: + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task progress --cluster d1d532cd-49f2-4c97-9263-25126532803b repair/d4946360-c29d-4bb4-8b9d-619ada495c2a +Status: RUNNING +Start time: 23 Sep 20 14:38:42 UTC +Duration: 13s +Progress: 2.69% +Datacenters: + - us-east-1 ++--------------------+-------+ +| system_auth | 8.06% | +| system_distributed | 0.00% | +| system_traces | 0.00% | ++--------------------+-------+ + +``` +Other tasks can be also tracked using the same command, but using different task ID. +Task IDs are present in Cluster Status as well as in task listing. + +## Clean Up + +To clean up all resources associated with Scylla Manager, you can run the commands below. + +**NOTE:** this will destroy your Scylla Manager database and delete all of its associated data. + +```console +kubectl delete -f examples/common/manager.yaml +``` + +## Troubleshooting + +**Manager is not running** + +If the Scylla Manager does not come up, the first step would be to examine the Manager and Controller logs: + +```console +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-controller +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-scylla-manager-7bd9f968b9-w25jw +``` + + +**My task wasn't scheduled** + +If your task wasn't scheduled, Cluster status will be updated with error messages for each failed task. +You can also consult Scylla Manager logs. + +Example: + +Following status describes error when backup task cannot be scheduled, due to lack of access to bucket: +```console +Status: + Backups: + Error: create backup target: location is not accessible: 10.100.16.62: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.100.16.62 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.107.193.33: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.107.193.33 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.109.197.60: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.109.197.60 and run "scylla-manager-agent check-location -L s3:manager-test --debug" + Id: 00000000-0000-0000-0000-000000000000 + Interval: 0 + Location: + s3:manager-test + Name: adhoc backup + Num Retries: 3 + Retention: 3 + Start Date: now + Manager Id: 2b9dbe8c-9daa-4703-a66d-c29f63a917c8 + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.0.0 +``` + +Because Controller is infinitely retrying to schedule each defined task, once permission issues will be resolved, +task should appear in task listing and Cluster status. \ No newline at end of file diff --git a/stable/_sources/migration.md.txt b/stable/_sources/migration.md.txt new file mode 100644 index 00000000000..cdd7a7e8522 --- /dev/null +++ b/stable/_sources/migration.md.txt @@ -0,0 +1,146 @@ +## Version migrations + + +### `v0.3.0` -> `v1.0.0` migration + +`v0.3.0` used a very common name as a CRD kind (`Cluster`). In `v1.0.0` this issue was solved by using less common kind +which is easier to disambiguate (`ScyllaCluster`). +***This change is backward incompatible, which means manual migration is needed.*** + +This procedure involves having two CRDs registered at the same time. We will detach Scylla Pods +from Scylla Operator for a short period to ensure that nothing is garbage collected when Scylla Operator is upgraded. +Compared to the [upgrade guide](upgrade.md) where full deletion is requested, this procedure shouldn't cause downtimes. +Although detaching resources from their controller is considered hacky. This means that you shouldn't run procedure +out of the box on production. Make sure this procedure works well multiple times on your staging environment first. + +***Read the whole procedure and make sure you understand what is going on before executing any of the commands!*** + +In case of any issues or questions regarding this procedure, you're welcomed on our [Scylla Users Slack](http://slack.scylladb.com/) +on #kubernetes channel. + +### Procedure + +1. Execute this whole procedure for each cluster sequentially. To get a list of existing clusters execute the following + ``` + kubectl -n scylla get cluster.scylla.scylladb.com + + NAME AGE + simple-cluster 30m + ``` + All below commands will use `scylla` namespace and `simple-cluster` as a cluster name. +1. Make sure you're using v1.0.0 tag: + ``` + git checkout v1.0.0 + ``` +1. Upgrade your `cert-manager` to `v1.0.0`. If you installed it from a static file from this repo, simply execute the following: + ``` + kubectl apply -f examples/common/cert-manager.yaml + ``` + If your `cert-manager` was installed in another way, follow official instructions on `cert-manager` website. +1. `examples/common/operator.yaml` file contains multiple resources. Extract **only** `CustomResourceDefinition` to separate file. +1. Install v1.0.0 CRD definition from file created in the previous step: + ``` + kubectl apply -f examples/common/crd.yaml + ``` +1. Save your existing `simple-cluster` Cluster definition to a file: + ``` + kubectl -n scylla get cluster.scylla.scylladb.com simple-cluster -o yaml > existing-cluster.yaml + ``` +1. Migrate `Kind` and `ApiVersion` to new values using: + ``` + sed -i 's/scylla.scylladb.com\/v1alpha1/scylla.scylladb.com\/v1/g' existing-cluster.yaml + sed -i 's/kind: Cluster/kind: ScyllaCluster/g' existing-cluster.yaml + ``` +1. Install migrated CRD instance + ``` + kubectl apply -f existing-cluster.yaml + ``` + At this point, we should have two CRDs describing your Scylla cluster, although the new one is not controlled by the Operator. +1. Get UUID of newly created ScyllaCluster resource: + ``` + kubectl -n scylla get ScyllaCluster simple-cluster --template="{{ .metadata.uid }}" + + 12a3678d-8511-4c9c-8a48-fa78d3992694 + ``` + Save output UUID somewhere, it will be referred as `` in commands below. + + ***Depending on your shell, you might get additional '%' sign at the end of UUID, make sure to remove it!*** + +1. Upgrade ClusterRole attached to each of the Scylla nodes to grant them permission to lookup Scylla clusters: + ``` + kubectl patch ClusterRole simple-cluster-member --type "json" -p '[{"op":"add","path":"/rules/-","value":{"apiGroups":["scylla.scylladb.com"],"resources":["scyllaclusters"],"verbs":["get"]}}]' + ``` + Amend role name according to your cluster name, it should look like `-member`. +1. Get a list of all Services associated with your cluster. First get list of all services: + ``` + kubectl -n scylla get svc -l "scylla/cluster=simple-cluster" + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 109m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.23.96 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 109m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.66.22 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 108m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.246.25 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 106m + + ``` +1. For each service, change its `ownerReference` to point to new CRD instance: + ``` + kubectl -n scylla patch svc --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":""}]' + ``` + Replace `` with Service name, and `` with saved UUID from one of the previous steps. +1. Get a list of all Services again to see if none was deleted. Check also "Age" column, it shouldn't be lower than previous result. + ``` + kubectl -n scylla get svc -l "scylla/cluster=simple-cluster" + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 110m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.23.96 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 110m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.66.22 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 109m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.246.25 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 107m + + ``` +1. Get a list of StatefulSets associated with your cluster: + ``` + kubectl -n scylla get sts -l "scylla/cluster=simple-cluster" + + NAME READY AGE + simple-cluster-us-east-1-us-east-1a 3/3 104m + ``` +1. For each StatefulSet from previous step, change its `ownerReference` to point to new CRD instance. + + ``` + kubectl -n scylla patch sts --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":""}]' + ``` + Replace `` with StatefulSet name, and `` with saved UUID from one of the previous steps. + +1. Now when all k8s resources bound to Scylla are attached to new CRD, we can remove 0.3.0 Operator and old CRD definition. + Checkout `v0.3.0` version, and remove Scylla Operator, and old CRD: + ``` + git checkout v0.3.0 + kubectl delete -f examples/generic/operator.yaml + ``` +1. Checkout `v1.0.0`, and install upgraded Scylla Operator: + ``` + git checkout v1.0.0 + kubectl apply -f examples/common/operator.yaml + ``` +1. Wait until Scylla Operator boots up: + ``` + kubectl -n scylla-operator-system wait --for=condition=ready pod --all --timeout=600s + ``` +1. Get a list of StatefulSets associated with your cluster: + ``` + kubectl -n scylla get sts -l "scylla/cluster=simple-cluster" + + NAME READY AGE + simple-cluster-us-east-1-us-east-1a 3/3 104m +1. For each StatefulSet from previous step, change its sidecar container image to `v1.0.0`, and wait until change will be propagated. This step will initiate a rolling restart of pods one by one. + ``` + kubectl -n scylla patch sts --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/initContainers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]' + kubectl -n scylla rollout status sts + ``` + Replace `` with StatefulSet name. +1. If you're using Scylla Manager, bump Scylla Manager Controller image to `v1.0.0` + ``` + kubectl -n scylla-manager-system patch sts scylla-manager-controller --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]' + ``` +1. Your Scylla cluster is now migrated to `v1.0.0`. diff --git a/stable/_sources/monitoring.md.txt b/stable/_sources/monitoring.md.txt new file mode 100644 index 00000000000..9f2651c5737 --- /dev/null +++ b/stable/_sources/monitoring.md.txt @@ -0,0 +1,180 @@ +# Monitoring + +Scylla Operator 1.8 introduced a new API resource `ScyllaDBMonitoring`, allowing users to deploy a managed monitoring +setup for their Scylla Clusters. + +```yaml +apiVersion: scylla.scylladb.com/v1alpha1 +kind: ScyllaDBMonitoring +metadata: + name: example +spec: + type: Platform + endpointsSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla-operator.scylladb.com/scylla-service-type: identity + scylla/cluster: replace-with-your-scyllacluster-name + components: + prometheus: + storage: + volumeClaimTemplate: + spec: + resources: + requests: + storage: 1Gi + grafana: + exposeOptions: + webInterface: + ingress: + ingressClassName: haproxy + dnsDomains: + - test-grafana.test.svc.cluster.local + annotations: + haproxy-ingress.github.io/ssl-passthrough: "true" +``` + +For details, refer to the below command: +```console +$ kubectl explain scylladbmonitorings.scylla.scylladb.com/v1alpha1 +``` + +## Deploy managed monitoring + +**Note**: as of v1.8, ScyllaDBMonitoring is experimental. The API is currently in version v1alpha1 and may change in future versions. + +### Requirements + +Before you can set up your ScyllaDB monitoring, you need Scylla Operator already installed in your Kubernetes cluster. +For more information on how to deploy Scylla Operator, see: +* [Deploying Scylla on a Kubernetes Cluster](generic.md) +* [Deploying Scylla stack using Helm Charts](helm.md) + +The above example of the monitoring setup also makes use of HAProxy Ingress and Prometheus Operator. +You can deploy them in your Kubernetes cluster using the provided third party examples. If you already have them deployed +in your cluster, you can skip the below steps. + +#### Deploy Prometheus Operator +Deploy Prometheus Operator using kubectl: +```console +$ kubectl -n prometheus-operator apply --server-side -f ./examples/third-party/prometheus-operator +``` + +##### Wait for Prometheus Operator to roll out +```console +$ kubectl -n prometheus-operator rollout status --timeout=5m deployments.apps/prometheus-operator +deployment "prometheus-operator" successfully rolled out +``` + +#### Deploy HAProxy Ingress +Deploy HAProxy Ingress using kubectl: +```console +$ kubectl -n haproxy-ingress apply --server-side -f ./examples/third-party/haproxy-ingress +``` + +##### Wait for HAProxy Ingress to roll out +```console +$ kubectl -n haproxy-ingress rollout status --timeout=5m deployments.apps/haproxy-ingress +deployment "haproxy-ingress" successfully rolled out +``` + +### Deploy ScyllaDBMonitoring + +First, update the `endpointsSelector` in `examples/monitoring/v1alpha1/scylladbmonitoring.yaml` with a label +matching your ScyllaCluster instance name. + +Deploy the monitoring setup using kubectl: +```console +$ kubectl -n scylla apply --server-side -f ./examples/monitoring/v1alpha1/scylladbmonitoring.yaml +``` + +Scylla Operator will notice the new ScyllaDBMonitoring object, and it will reconcile all necessary resources. + +#### Wait for ScyllaDBMonitoring to roll out +```console +$ kubectl wait --for='condition=Progressing=False' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met + +$ kubectl wait --for='condition=Degraded=False' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met + +$ kubectl wait --for='condition=Available=True' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met +``` + +#### Wait for Prometheus to roll out +```console +$ kubectl rollout status --timeout=5m statefulset.apps/prometheus-example +statefulset rolling update complete 1 pods at revision prometheus-example-65b89d55bb... +``` + +#### Wait for Grafana to roll out +```console +$ kubectl rollout status --timeout=5m deployments.apps/example-grafana +deployment "example-grafana" successfully rolled out +``` + +### Accessing Grafana + +For accessing Grafana service from outside the Kubernetes cluster we recommend using an Ingress, although there are many other ways to do so. +When using Ingress, what matters is to direct your packets to the ingress controller Service/Pods and have the correct TLS SNI field set by the caller when reaching out to the service, so it is routed properly, and your client can successfully validate the grafana serving certificate. +This is easier when you are using a real DNS domain that resolves to your Ingress controller's IP address but most clients and tools allow setting the SNI field manually. + +### Prerequisites + +To access Grafana, you first need to collect the serving CA and the credentials. + +```console +$ GRAFANA_SERVING_CERT="$( kubectl -n scylla get secret/example-grafana-serving-ca --template '{{ index .data "tls.crt" }}' | base64 -d )" +$ GRAFANA_USER="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "username" }}' | base64 -d )" +$ GRAFANA_PASSWORD="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "password" }}' | base64 -d )" +``` + +### Connecting through Ingress using a resolvable domain + +In production clusters, the Ingress controller and appropriate DNS records should be set up already. Often there is already a generic wildcard record like `*.app.mydomain` pointing to the Ingress controller's external IP. For custom service domains, it is usually a CNAME pointing to the Ingress controller's A record. + +Note: The ScyllaDBMonitoring example creates an Ingress object with `test-grafana.test.svc.cluster.local` DNS domain that you should adjust to your domain. Below examples use `example-grafana.apps.mydomain`. + +Note: To test a resolvable domain from your machine without creating DNS records, you can adjust `/etc/hosts` or similar. + +```console +$ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://example-grafana.apps.mydomain" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}" +200 +``` + +### Connecting through Ingress using an unresolvable domain + +To connect to an Ingress without a resolvable domain you first need to find out your Ingress controller's IP that can be resolved externally. Again, there are many ways to do so beyond the below examples. + +Unless stated otherwise, we assume your Ingress is running on port 443. + +```console +$ INGRESS_PORT=443 +``` + +#### Variants + +##### Ingress ExternalIP + +When you are running in a real cluster there is usually a cloud LoadBalancer or a bare metal alternative providing you with an externally reachable IP address. + +```console +$ INGRESS_IP="$( kubectl -n=haproxy-ingress get service/haproxy-ingress --template='{{ ( index .status.loadBalancer.ingress 0 ).ip }}' )" +``` + +##### Ingress NodePort + +NodePort is slightly less convenient, but it's available in development clusters as well. + +```console +$ INGRESS_IP="$( kubectl get nodes --template='{{ $internal_ip := "" }}{{ $external_ip := "" }}{{ range ( index .items 0 ).status.addresses }}{{ if eq .type "InternalIP" }}{{ $internal_ip = .address }}{{ else if eq .type "ExternalIP" }}{{ $external_ip = .address }}{{ end }}{{ end }}{{ if $external_ip }}{{ $external_ip }}{{ else }}{{ $internal_ip }}{{ end }}' )" +$ INGRESS_PORT="$( kubectl -n=haproxy-ingress get services/haproxy-ingress --template='{{ range .spec.ports }}{{ if eq .port 443 }}{{ .nodePort }}{{ end }}{{ end }}' )" +``` + +##### Connection + +```console +$ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://test-grafana.test.svc.cluster.local:${INGRESS_PORT}" --resolve "test-grafana.test.svc.cluster.local:${INGRESS_PORT}:${INGRESS_IP}" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}" +200 +``` diff --git a/stable/_sources/multidc/eks.md.txt b/stable/_sources/multidc/eks.md.txt new file mode 100644 index 00000000000..266dd7d3a4d --- /dev/null +++ b/stable/_sources/multidc/eks.md.txt @@ -0,0 +1,168 @@ +# Build multiple Amazon EKS clusters with inter-Kubernetes networking + +This document describes the process of creating multiple Amazon EKS clusters in different regions, using separate VPCs, and explains the steps necessary for configuring inter-Kubernetes networking between the clusters. +The interconnected clusters can serve as a platform for [deploying a multi-datacenter ScyllaDB cluster](multidc.md). + +This guide will walk you through the process of creating and configuring EKS clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference. + +## Prerequisites + +To follow the below guide, you first need to install and configure the tools that you will need to create and manage AWS and Kubernetes resources: +- eksctl – A command line tool for working with EKS clusters. +- kubectl – A command line tool for working with Kubernetes clusters. + +For more information see [Getting started with Amazon EKS – eksctl](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html) in AWS documentation. + +## Create EKS clusters + +### Create the first EKS cluster + +Below is the required specification for the first cluster. + +```yaml +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig + +metadata: + name: scylladb-us-east-1 + region: us-east-1 + +availabilityZones: +- us-east-1a +- us-east-1b +- us-east-1c + +vpc: + cidr: 10.0.0.0/16 + +nodeGroups: + ... +``` + +Specify the first cluster's configuration file and save it as `cluster-us-east-1.yaml`. +Refer to [Creating an EKS cluster](../eks.md#creating-an-eks-cluster) section of ScyllaDB Operator documentation for the reference of the configuration of node groups. + +To deploy the first cluster, use the below command: +```shell +eksctl create cluster -f=cluster-us-east-1.yaml +``` + +Run the following command to learn the status and VPC ID of the cluster: +```shell +eksctl get cluster --name=scylladb-us-east-1 --region=us-east-1 +``` + +You will need to get the cluster's context for future operations. To do so, use the below command: +```shell +kubectl config current-context +``` + +For any `kubectl` commands that you will want to run against this cluster, use the `--context` flag with the value returned by the above command. + +#### Deploy ScyllaDB Operator + +Once the cluster is ready, refer to [Deploying Scylla on a Kubernetes Cluster](../generic.md) to deploy the ScyllaDB Operator and its prerequisites. + +#### Prepare nodes for running ScyllaDB + +Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in [Deploying Scylla on EKS](../eks.md#prerequisites) in ScyllaDB Operator documentation. + +### Create the second EKS cluster + +Below is the required specification for the second cluster. As was the case with the first cluster, the provided values are only exemplary and can be adjusted according to your needs. + +:::{caution} +It is required that the VPCs of the two EKS clusters have non-overlapping IPv4 network ranges. +::: + +```yaml +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig + +metadata: + name: scylladb-us-east-2 + region: us-east-2 + +availabilityZones: +- us-east-2a +- us-east-2b +- us-east-2c + +vpc: + cidr: 172.16.0.0/16 + +nodeGroups: + ... +``` + +Follow analogous steps to create the second EKS cluster and prepare it for running ScyllaDB. + +## Configure the network + +The prepared Kubernetes clusters each have a dedicated VPC network. +To be able to route the traffic between the two VPC networks, you need to create a networking connection between them, otherwise known as [VPC peering](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html). + +### Create VPC peering + +Refer to [Create a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/create-vpc-peering-connection.html#create-vpc-peering-connection-local) in AWS documentation for instructions on creating a VPC peering connection between the two earlier created VPCs. + +In this example, the ID of the created VPC peering connection is `pcx-08077dcc008fbbab6`. + +### Update route tables + +To enable private IPv4 traffic between the instances in the VPC peered network, you need to establish a communication channel by adding a route to the route tables associated with all the subnets associated with the instances for both VPCs. +The destination of the new route in a given route table is the CIDR of the VPC of the other cluster and the target is the ID of the VPC peering connection. + +The following is an example of the route tables that enable communication of instances in two peered VPCs. Each table has a local route and the added route which sends traffic targeted at the other VPC to the peered network connection. The other preconfigured routes are omitted for readability. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Route tableDestinationTarget
      eksctl-scylladb-us-east-1-cluster/PublicRouteTable10.0.0.0/16local
      172.16.0.0/16pcx-08077dcc008fbbab6
      eksctl-scylladb-us-east-2-cluster/PublicRouteTable172.16.0.0/16local
      10.0.0.0/16pcx-08077dcc008fbbab6
      + + +Refer to [Update your route tables for a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-routing.html) in AWS documentation for more information. + +### Update security groups + +To allow traffic to flow to and from instances associated with security groups in the peered VPC, you need to update the inbound rules of the VPCs' shared security groups. + +Below is an example of the inbound rules that to be added to the corresponding security groups of the two VPCs. + +| Security group name | Type | Protocol | Port range | Source | +|--------------------------------------------------------------------------------|-------------|----------|------------|----------------------| +| eksctl-scylladb-us-east-1-cluster-ClusterSharedNodeSecurityGroup-TD05V9EVU3B8 | All traffic | All | All | Custom 172.16.0.0/16 | +| eksctl-scylladb-us-east-2-cluster-ClusterSharedNodeSecurityGroup-1FR9YDLU0VE7M | All traffic | All | All | Custom 10.0.0.0/16 | + +The names of the shared security groups of your VPCs should be similar to the ones presented in the example. + +--- + +Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to [Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters](multidc.md) in ScyllaDB Operator documentation for guidance. diff --git a/stable/_sources/multidc/gke.md.txt b/stable/_sources/multidc/gke.md.txt new file mode 100644 index 00000000000..b119d9e9b3b --- /dev/null +++ b/stable/_sources/multidc/gke.md.txt @@ -0,0 +1,156 @@ +# Build multiple GKE clusters with inter-Kubernetes networking + +This document describes the process of creating multiple GKE clusters in a shared VPC and explains the steps necessary for configuring inter-Kubernetes networking between clusters in different regions. +The interconnected clusters can serve as a platform for [deploying a Multi Datacenter ScyllaDB cluster](multidc.md). + +This guide will walk you through the process of creating and configuring GKE clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference. + +## Prerequisites + +To follow the below guide, you first need to install and configure the following tools that you will need to create and manage GCP and Kubernetes resources: +- gcloud CLI - Google Cloud Command Line Interface, a command line tool for working with Google Cloud resources and services directly. +- kubectl – A command line tool for working with Kubernetes clusters. + +See [Install the Google Cloud CLI](https://cloud.google.com/sdk/docs/install-sdk) in GCP documentation and [Install Tools](https://kubernetes.io/docs/tasks/tools/) in Kubernetes documentation for reference. + +## Create and configure a VPC network + +For the clusters to have inter-Kubernetes networking, you will create a virtual network shared between all the instances, with dedicated subnets for each of the clusters. +To create the subnets manually, create the network in custom subnet mode. + +### Create the VPC network + +Run the below command to create the network: +```shell +gcloud compute networks create scylladb --subnet-mode=custom +``` + +With the VPC network created, create a dedicated subnet with secondary CIDR ranges for their Pod and Service pools in each region which the clusters will reside in. + +### Create VPC network subnets + +To create a subnet for the first cluster in region `us-east1`, run the below command: +```shell +gcloud compute networks subnets create scylladb-us-east1 \ + --region=us-east1 \ + --network=scylladb \ + --range=10.0.0.0/20 \ + --secondary-range='cluster=10.1.0.0/16,services=10.2.0.0/20' +``` + +To create a subnet for the second cluster in region `us-west1`, run the below command: +```shell +gcloud compute networks subnets create scylladb-us-west1 \ + --region=us-west1 \ + --network=scylladb \ + --range=172.16.0.0/20 \ + --secondary-range='cluster=172.17.0.0/16,services=172.18.0.0/20' +``` + +:::{caution} +It is required that the IPv4 address ranges of the subnets allocated for the GKE clusters do not overlap. +::: + +Refer to [Create a VPC-native cluster](https://cloud.google.com/kubernetes-engine/docs/how-to/alias-ips) and [Alias IP ranges](https://cloud.google.com/vpc/docs/alias-ip) in GKE documentation for more information about VPC native clusters and alias IP ranges. + +## Create GKE clusters + +With the VPC network created, you will now create two VPC native GKE clusters in dedicated regions. + +### Create the first GKE cluster + +Run the following command to create the first GKE cluster in the `us-east1` region: +```shell +gcloud container clusters create scylladb-us-east1 \ + --location=us-east1-b \ + --node-locations='us-east1-b,us-east1-c' \ + --machine-type=n1-standard-8 \ + --num-nodes=1 \ + --disk-type=pd-ssd \ + --disk-size=20 \ + --image-type=UBUNTU_CONTAINERD \ + --no-enable-autoupgrade \ + --no-enable-autorepair \ + --enable-ip-alias \ + --network=scylladb \ + --subnetwork=scylladb-us-east1 \ + --cluster-secondary-range-name=cluster \ + --services-secondary-range-name=services +``` + +Refer to [Creating a GKE cluster](../gke.md#creating-a-gke-cluster) section of ScyllaDB Operator documentation for more information regarding the configuration and deployment of additional node pools, including the one dedicated for ScyllaDB nodes. + +You will need to get the cluster's context for future operations. To do so, use the below command: +```shell +kubectl config current-context +``` + +For any `kubectl` commands that you will want to run against this cluster, use the `--context` flag with the value returned by the above command. + +#### Deploy ScyllaDB Operator + +Once the cluster is ready, refer to [Deploying Scylla on a Kubernetes Cluster](../generic.md) to deploy the ScyllaDB Operator and its prerequisites. + +#### Prepare nodes for running ScyllaDB + +Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in [Deploying Scylla on GKE](../gke.md) page of the documentation. + +### Create the second GKE cluster + +Run the following command to create the second GKE cluster in the `us-west1` region: +```shell +gcloud container clusters create scylladb-us-west1 \ + --location=us-west1-b \ + --node-locations='us-west1-b,us-west1-c' \ + --machine-type=n1-standard-8 \ + --num-nodes=1 \ + --disk-type=pd-ssd \ + --disk-size=20 \ + --image-type=UBUNTU_CONTAINERD \ + --no-enable-autoupgrade \ + --no-enable-autorepair \ + --enable-ip-alias \ + --network=scylladb \ + --subnetwork=scylladb-us-west1 \ + --cluster-secondary-range-name=cluster \ + --services-secondary-range-name=services +``` + +Follow analogous steps to create the second GKE cluster and prepare it for running ScyllaDB. + +## Configure the firewall rules + +When creating a cluster, GKE creates several ingress firewall rules that enable the instances to communicate with each other. +To establish interconnectivity between the two created Kubernetes clusters, you will now add the allocated IPv4 address ranges to their corresponding source address ranges. + +First, retrieve the name of the firewall rule associated with the first cluster, which permits traffic between all Pods on a cluster, as required by the Kubernetes networking model. +The rule name is in the following format: `gke-[cluster-name]-[cluster-hash]-all`. + +To retrieve it, run the below command: +```shell +gcloud compute firewall-rules list --filter='name~gke-scylladb-us-east1-.*-all' +``` + +The output should resemble the following: +```console +NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED +gke-scylladb-us-east1-f17db261-all scylladb INGRESS 1000 udp,icmp,esp,ah,sctp,tcp False +``` + +Modify the rule by updating the rule's source ranges with the allocated Pod IPv4 address ranges of both clusters: +```shell +gcloud compute firewall-rules update gke-scylladb-us-east1-f17db261-all --source-ranges='10.1.0.0/16,172.17.0.0/16' +``` + +Follow the analogous steps for the other cluster. In this example, its corresponding firewall rule name is `gke-scylladb-us-west1-0bb60902-all`. To update it, you would run: +```shell +gcloud compute firewall-rules update gke-scylladb-us-west1-0bb60902-all --source-ranges='10.1.0.0/16,172.17.0.0/16' +``` + +Refer to [Automatically created firewall rules](https://cloud.google.com/kubernetes-engine/docs/concepts/firewall-rules) in GKE documentation for more information. + +--- + +Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to [Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters](multidc.md) in ScyllaDB Operator documentation for guidance. diff --git a/stable/_sources/multidc/index.rst.txt b/stable/_sources/multidc/index.rst.txt new file mode 100644 index 00000000000..52a87126e8a --- /dev/null +++ b/stable/_sources/multidc/index.rst.txt @@ -0,0 +1,25 @@ +========================================================== +Deploying multi-datacenter ScyllaDB clusters in Kubernetes +========================================================== + +Prepare a platform for a multi datacenter ScyllaDB cluster deployment: + +.. toctree:: + :hidden: + :maxdepth: 2 + + eks + gke + +* :doc:`Build multiple Amazon EKS clusters with Inter-Kubernetes networking ` +* :doc:`Build multiple GKE clusters with Inter-Kubernetes networking ` + +Deploy a multi-datacenter ScyllaDB cluster in Kubernetes: + +.. toctree:: + :hidden: + :maxdepth: 2 + + multidc + +* :doc:`Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters ` diff --git a/stable/_sources/multidc/multidc.md.txt b/stable/_sources/multidc/multidc.md.txt new file mode 100644 index 00000000000..33435f7ab22 --- /dev/null +++ b/stable/_sources/multidc/multidc.md.txt @@ -0,0 +1,601 @@ +# Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters + +This document describes the process of deploying a Multi Datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters. + +This guide will walk you through the example procedure of deploying two datacenters in distinct regions of a selected cloud provider. + +:::{note} +This guide is dedicated to deploying multi-datacenter ScyllaDB clusters and does not discuss unrelated configuration options. +For details of ScyllaDB cluster deployments and their configuration, refer to [Deploying Scylla on a Kubernetes Cluster](../generic.md) in ScyllaDB Operator documentation. +::: + +## Prerequisites + +As this document describes the procedure of deploying a Multi Datacenter ScyllaDB cluster, you are expected to have the required infrastructure prepared. +Let's assume two interconnected Kubernetes clusters, capable of communicating with each other over PodIPs, with each cluster meeting the following requirements: +- a node pool dedicated to ScyllaDB nodes composed of at least 3 nodes running in different zones (with unique `topology.kubernetes.io/zone` label), configured to run ScyllaDB, each labeled with `scylla.scylladb.com/node-type: scylla` +- running ScyllaDB Operator and its prerequisites +- running a storage provisioner capable of provisioning XFS volumes of StorageClass `scylladb-local-xfs` in each of the nodes dedicated to ScyllaDB instances + +You can refer to one of our guides describing the process of preparing such infrastructure: +- [Build multiple Amazon EKS clusters with Inter-Kubernetes networking](eks.md) +- [Build multiple GKE clusters with Inter-Kubernetes networking](gke.md) + +Additionally, to follow the below guide, you need to install and configure the following tools that you will need to manage Kubernetes resources: +- kubectl – A command line tool for working with Kubernetes clusters. + +See [Install Tools](https://kubernetes.io/docs/tasks/tools/) in Kubernetes documentation for reference. + +## Multi Datacenter ScyllaDB Cluster + +In v1.11, ScyllaDB Operator introduced support for manual multi-datacenter ScyllaDB cluster deployments. + +:::{warning} +ScyllaDB Operator only supports *manual configuration* of multi-datacenter ScyllaDB clusters. +In other words, although ScyllaCluster API exposes the machinery necessary for setting up multi-datacenter ScylaDB clusters, the ScyllaDB Operator only automates operations for a single datacenter. + +Operations related to multiple datacenters may require manual intervention of a human operator. +Most notably, destroying one of the Kubernetes clusters or ScyllaDB datacenters is going to leave DN nodes behind in other datacenters, and their removal has to be carried out manually. +::: + +The main mechanism used to set up a manual multi-datacenter ScyllaDB cluster is a field in ScyllaCluster's specification - `externalSeeds`. + +### External seeds + +The `externalSeeds` field in ScyllaCluster's specification enables control over external seeds that are propagated to ScyllaDB binary as `--seed-provider-parameters seeds=`. +In this context, external should be understood as "external to the datacenter being specified by the API". +The provided seeds are used by the nodes as initial points of contact, which allows them to discover the cluster ring topology when joining it. + +Refer to [Scylla Seed Nodes](https://opensource.docs.scylladb.com/stable/kb/seed-nodes.html) in ScyllaDB documentation for more information regarding the function of seed nodes in ScyllaDB. +For more details regarding the function and implementation of external seeds, refer to [the original enhancement proposal](https://github.com/scylladb/scylla-operator/tree/v1.11/enhancements/proposals/1304-external-seeds). + +### Networking + +Since this guide assumes interconnectivity over PodIPs of the Kubernetes clusters, you are going to configure the ScyllaDB cluster's nodes to communicate over PodIPs. +This is enabled by a subset of `exposeOptions` specified in ScyllaCluster API, introduced in v1.11. + +For this particular setup, define the ScyllaClusers as follows: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: Headless + broadcastOptions: + clients: + type: PodIP + nodes: + type: PodIP +``` + +However, other configuration options allow for the manual deployment of multi-datacenter ScyllaDB clusters in different network setups. For details, refer to [Exposing ScyllaClusters](../exposing.md) in ScyllaDB Operator documentation. + +#### Deploy a multi-datacenter ScyllaDB Cluster + +#### Using context + +Let's specify contexts for `kubectl` commands used throughout the guide. +To retrieve the context of your current cluster, run: +```shell +kubectl config current-context +``` + +Save the contexts of the two clusters, which you are going to deploy the datacenters in, as `CONTEXT_DC1` and `CONTEXT_DC2` environment variables correspondingly. + +#### Deploy the first datacenter + +First, run the below command to create a dedicated 'scylla' namespace: +```shell +kubectl --context="${CONTEXT_DC1}" create ns scylla +``` + +For this guide, let's assume that your cluster is running in `us-east-1` region and the nodes dedicated to running ScyllaDB nodes are running in zones `us-east-1a`, `us-east-1b` and `us-east-1c` correspondingly. If that is not the case, adjust the manifest accordingly. + +:::{caution} +The `.spec.name` field of the ScyllaCluster objects represents the ScyllaDB cluster name and has to be consistent across all datacenters of this ScyllaDB cluster. +The names of the datacenters, specified in `.spec.datacenter.name`, have to be unique across the entire multi-datacenter cluster. + +For more information see [Create a ScyllaDB Cluster - Multi Data Centers (DC)](https://opensource.docs.scylladb.com/stable/operating-scylla/procedures/cluster-management/create-cluster-multidc.html) in ScyllaDB documentation. +::: + +Save the ScyllaCluster manifest in `dc1.yaml`: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: scylla-cluster + namespace: scylla +spec: + version: 5.2.7 + agentVersion: 3.1.2 + cpuset: true + sysctls: + - "fs.aio-max-nr=2097152" + automaticOrphanedNodeCleanup: true + exposeOptions: + broadcastOptions: + clients: + type: PodIP + nodes: + type: PodIP + nodeService: + type: Headless + datacenter: + name: us-east-1 + racks: + - name: a + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-1a + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule + - name: b + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-1b + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule + - name: c + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-1c + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule +``` + +Apply the manifest: +```shell +kubectl --context="${CONTEXT_DC1}" apply --server-side -f=dc1.yaml +``` + +Wait for the cluster to be fully rolled out: +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +You can now verify that all the nodes of your cluster are in UN state: +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla exec -it pod/scylla-cluster-us-east-1-a-0 -c=scylla -- nodetool status +``` + +The expected output should look similar to the below: +```console +Datacenter: us-east-1 +===================== +Status=Up/Down +|/ State=Normal/Leaving/Joining/Moving +-- Address Load Tokens Owns Host ID Rack +UN 10.0.70.195 290 KB 256 ? 494277b9-121c-4af9-bd63-3d0a7b9305f7 c +UN 10.0.59.24 559 KB 256 ? a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37 b +UN 10.0.19.237 107 KB 256 ? 64b6292a-327f-4128-852a-6004039f402e a +``` + +##### Retrieve PodIPs of ScyllaDB nodes for use as external seeds + +:::{warning} +Due to the ephemeral nature of PodIPs, it is ill-advised to use them as seeds in production environments. +This is because there is a high likelihood that the Pods of your ScyllaDB clusters will change their IPs during the cluster's lifecycle, and so the provided seeds will no longer point to the ScyllaDB nodes. +It is undesired, as the seeds provided on node's startup may serve as fallback contact points when all of the node's peers are unreachable. +In production environments, it is recommended that you use domain names or non-ephemeral IP addresses as external seeds. +PodIPs are being used in this example for the sheer simplicity of this setup. +::: + +Use the below commands and their expected outputs as a reference for retrieving the PodIPs used by the cluster for inter-node communication. +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-a-0 --template='{{ .status.podIP }}' +``` +```console +10.0.19.237 +``` + +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-b-0 --template='{{ .status.podIP }}' +``` +```console +10.0.59.24 +``` + +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-c-0 --template='{{ .status.podIP }}' +``` +```console +10.0.70.195 +``` + +You are going to utilize the retrieved addresses as seeds for the other datacenter. + +#### Deploy the second datacenter + +To deploy the second datacenter, you will follow similar steps. + +First, create a dedicated 'scylla' namespace: +```shell +kubectl --context="${CONTEXT_DC2}" create ns scylla +``` + +Replace the values in `.spec.externalSeeds` of the below manifest with the Pod IP addresses that you retrieved earlier. +The provided values are going to serve as initial contact points for the joining nodes of the second datacenter. + +For this guide, let's assume that the second cluster is running in `us-east-2` region and the nodes dedicated for running ScyllaDB nodes are running in zones `us-east-2a`, `us-east-2b` and `us-east-2c` correspondingly. If that is not the case, adjust the manifest accordingly. +Having configured it, save the manifest as `dc2.yaml`: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: scylla-cluster + namespace: scylla +spec: + version: 5.2.7 + agentVersion: 3.1.2 + cpuset: true + sysctls: + - "fs.aio-max-nr=2097152" + automaticOrphanedNodeCleanup: true + exposeOptions: + broadcastOptions: + clients: + type: PodIP + nodes: + type: PodIP + nodeService: + type: Headless + externalSeeds: + - 10.0.19.237 + - 10.0.59.24 + - 10.0.70.195 + datacenter: + name: us-east-2 + racks: + - name: a + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-2a + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule + - name: b + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-2b + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule + - name: c + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-2c + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule +``` + +To apply the manifest, run: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla apply --server-side -f=dc2.yaml +``` + +Wait for the second datacenter to roll out: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +You can verify that the nodes have joined the existing cluster and that you are now running a multi-datacenter ScyllaDB cluster by running `nodetool status` with the below command: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla exec -it pod/scylla-cluster-us-east-2-a-0 -c=scylla -- nodetool status +``` +```console +Datacenter: us-east-1 +===================== +Status=Up/Down +|/ State=Normal/Leaving/Joining/Moving +-- Address Load Tokens Owns Host ID Rack +UN 10.0.70.195 705 KB 256 ? 494277b9-121c-4af9-bd63-3d0a7b9305f7 c +UN 10.0.59.24 764 KB 256 ? a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37 b +UN 10.0.19.237 634 KB 256 ? 64b6292a-327f-4128-852a-6004039f402e a +Datacenter: us-east-2 +===================== +Status=Up/Down +|/ State=Normal/Leaving/Joining/Moving +-- Address Load Tokens Owns Host ID Rack +UN 172.16.39.209 336 KB 256 ? 7c30ea55-7a4f-4d93-86f7-c881772ebe62 b +UN 172.16.25.18 759 KB 256 ? 665dde7e-e420-4db3-8c54-ca71efd39b2e a +UN 172.16.87.27 503 KB 256 ? c19c89cb-e24c-4062-9df4-2aa90ab29a99 c +``` + +## Scylla Manager + +To integrate a multi-datacenter ScyllaDB cluster with Scylla Manager, you must deploy the Scylla Manager in only one datacenter. + +In this example, let's choose the Kubernetes cluster deployed in the first datacenter to host it. +To deploy Scylla Manager, follow the steps described in [Deploying Scylla Manager on a Kubernetes Cluster](../manager.md) +in ScyllaDB Operator documentation. + +In order to define the Scylla Manager tasks, add them to the ScyllaCluster object deployed in the same Kubernetes cluster +in which your Scylla Manager is running. + +Every datacenter (represented by ScyllaCluster CR) is, by default, provisioned with a new, random Scylla Manager Agent auth token. +To use Scylla Manager with multiple datacenter (represented by ScyllaClusters), you have to make sure they all use the same token. + +Extract it from the first datacenter with the below command: +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla get secrets/scylla-cluster-auth-token --template='{{ index .data "auth-token.yaml" }}' | base64 -d +``` +```console +auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf +``` + +Save the output, replace the token with your own, and patch the secret in the second datacenter with the below command: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla patch secret/scylla-cluster-auth-token--type='json' -p='[{"op": "add", "path": "/stringData", "value": {"auth-token.yaml": "auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf"}}]' +``` + +Execute a rolling restart of the nodes in DC2 to make sure they pick up the new token: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla patch scyllacluster/scylla-cluster --type='merge' -p='{"spec": {"forceRedeploymentReason": "sync scylla-manager-agent token ('"$( date )"')"}}' +``` + + +## ScyllaDBMonitoring + +To monitor your cluster, deploy ScyllaDBMonitoring in every datacenter independently. +To deploy ScyllaDB Monitoring, follow the steps described in [Deploy managed monitoring](../monitoring.md#deploy-managed-monitoring) in ScyllaDB Operator documentation. diff --git a/stable/_sources/nodeoperations/automatic-cleanup.md.txt b/stable/_sources/nodeoperations/automatic-cleanup.md.txt new file mode 100644 index 00000000000..5e0535cca97 --- /dev/null +++ b/stable/_sources/nodeoperations/automatic-cleanup.md.txt @@ -0,0 +1,6 @@ +# Automatic cleanup and replacement in case when k8s node is lost + +In case when your k8s cluster loses one of the nodes due to incident or explicit removal, Scylla Pods may become unschedulable due to PVC node affinity. + +When `automaticOrphanedNodeCleanup` flag is enabled in your ScyllaCluster, Scylla Operator will perform automatic +node replacement of a Pod which lost his bound resources. diff --git a/stable/_sources/nodeoperations/index.rst.txt b/stable/_sources/nodeoperations/index.rst.txt new file mode 100644 index 00000000000..c04919e5d13 --- /dev/null +++ b/stable/_sources/nodeoperations/index.rst.txt @@ -0,0 +1,22 @@ +====================================== +Node operations using Scylla Operator +====================================== + +.. toctree:: + :hidden: + :maxdepth: 2 + + scylla-upgrade + replace-node + automatic-cleanup + maintenance-mode + restore + + +Choose a topic: + +* :doc:`Scylla version upgrade ` +* :doc:`Replace Scylla node ` +* :doc:`Automatic cleanup and replacement when k8s node is lost ` +* :doc:`Maintenance mode ` +* :doc:`Restore from backup ` \ No newline at end of file diff --git a/stable/_sources/nodeoperations/maintenance-mode.md.txt b/stable/_sources/nodeoperations/maintenance-mode.md.txt new file mode 100644 index 00000000000..c976ecc2b87 --- /dev/null +++ b/stable/_sources/nodeoperations/maintenance-mode.md.txt @@ -0,0 +1,19 @@ +# Maintenance mode + +When maintenance mode is enabled, readiness probe of Scylla Pod will always return failure and liveness probe will always succeed. This causes that Pod under maintenance +is being removed from K8s Load Balancer and DNS registry but Pod itself stays alive. + +This allows the Scylla Operator to interact with Scylla and Scylla dependencies inside the Pod. +For example user may turn off Scylla process, do something with the filesystem and bring the process back again. + +To enable maintenance mode add `scylla/node-maintenance` label to service in front of Scylla Pod. + +```bash +kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance="" +``` + +To disable, simply remove this label from service. + +```bash +kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance- +``` diff --git a/stable/_sources/nodeoperations/replace-node.md.txt b/stable/_sources/nodeoperations/replace-node.md.txt new file mode 100644 index 00000000000..3e6a8c7f024 --- /dev/null +++ b/stable/_sources/nodeoperations/replace-node.md.txt @@ -0,0 +1,74 @@ +# Replacing a Scylla node + +## Replacing a dead node +In the case of a host failure, it may not be possible to bring back the node to life. + +Replace dead node operation will cause the other nodes in the cluster to stream data to the node that was replaced. +This operation can take some time (depending on the data size and network bandwidth). + +_This procedure is for replacing one dead node. To replace more than one dead node, run the full procedure to completion one node at a time_ + +**Procedure** + +1. Verify the status of the node using `nodetool status` command, the node with status DN is down and need to be replaced + ```bash + kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status + Datacenter: us-east-1 + ===================== + Status=Up/Down + |/ State=Normal/Leaving/Joining/Moving + -- Address Load Tokens Owns Host ID Rack + UN 10.43.125.110 74.63 KB 256 ? 8ebd6114-969c-44af-a978-87a4a6c65c3e us-east-1a + UN 10.43.231.189 91.03 KB 256 ? 35d0cb19-35ef-482b-92a4-b63eee4527e5 us-east-1a + DN 10.43.43.51 74.77 KB 256 ? 1ffa7a82-c41c-4706-8f5f-4d45a39c7003 us-east-1a + ``` +1. Identify service which is bound to down node by checking IP address + ```bash + kubectl -n scylla get svc + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 3h12m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.231.189 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h12m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.125.110 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h11m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.43.51 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h5m + ``` +1. Drain node which we would like to replace using. **This command may delete your data from local disks attached to given node!** + ```bash + kubectl drain gke-scylla-demo-default-pool-b4b390a1-6j12 --ignore-daemonsets --delete-local-data + ``` + + Pod which will be replaced should enter the `Pending` state + ```bash + kubectl -n scylla get pods + NAME READY STATUS RESTARTS AGE + simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 3h21m + simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 3h19m + simple-cluster-us-east-1-us-east-1a-2 0/2 Pending 0 8m14s + ``` +1. To being node replacing, add `scylla/replace=""` label to service bound to pod we are replacing. + ```bash + kubectl -n scylla label svc simple-cluster-us-east-1-us-east-1a-2 scylla/replace="" + ``` + Your failed Pod should be recreated on available k8s node + ```bash + kubectl -n scylla get pods + NAME READY STATUS RESTARTS AGE + simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 3h27m + simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 3h25m + simple-cluster-us-east-1-us-east-1a-2 1/2 Running 0 9s + ``` + Because other nodes in cluster must stream data to new node this operation might take some time depending on how much data your cluster stores. + After bootstraping is over, your new Pod should be ready to go. + Old one shouldn't be no longer visible in `nodetool status` + ```bash + kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status + Datacenter: us-east-1 + ===================== + Status=Up/Down + |/ State=Normal/Leaving/Joining/Moving + -- Address Load Tokens Owns Host ID Rack + UN 10.43.125.110 74.62 KB 256 ? 8ebd6114-969c-44af-a978-87a4a6c65c3e us-east-1a + UN 10.43.231.189 91.03 KB 256 ? 35d0cb19-35ef-482b-92a4-b63eee4527e5 us-east-1a + UN 10.43.191.172 74.77 KB 256 ? 1ffa7a82-c41c-4706-8f5f-4d45a39c7003 us-east-1a + ``` +1. Run the repair on the cluster to make sure that the data is synced with the other nodes in the cluster. + You can use [Scylla Manager](../manager.md) to run the repair. diff --git a/stable/_sources/nodeoperations/restore.md.txt b/stable/_sources/nodeoperations/restore.md.txt new file mode 100644 index 00000000000..f8ac607d9d6 --- /dev/null +++ b/stable/_sources/nodeoperations/restore.md.txt @@ -0,0 +1,217 @@ +# Restore from backup + +This procedure will describe how to restore from backup taken using [Scylla Manager](../manager.md) to a fresh **empty** cluster of any size. + +:::{caution} +Due to a [bug](https://github.com/scylladb/scylla-manager/issues/3679) in Scylla Manager not supporting ScyllaClusters having both non-TLS and TLS CQL ports open, you have to disable the TLS certificate management +in Scylla Operator. +This step will no longer be required, when the bug is fixed. + +To disable TLS certificate management in Scylla Operator add `--feature-gates="AutomaticTLSCertificates=false"` flag to Scylla Operator deployment. + +```console +kubectl -n scylla-operator patch deployment/scylla-operator --type=json -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--feature-gates=AutomaticTLSCertificates=false"}]' +``` + +::: + +In the following example, the ScyllaCluster, which was used to take the backup, is called `source`. Backup will be restored into the ScyllaCluster named `target`. + +::::{tab-set} +:::{tab-item} Source ScyllaCluster +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: source + namespace: scylla +spec: + agentVersion: 3.2.5 + version: 5.4.1 + developerMode: true + backups: + - name: foo + location: + - s3:source-backup + keyspace: + - '*' + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 1 + storage: + capacity: 1Gi + resources: + limits: + cpu: 1 + memory: 1Gi +``` +::: +:::{tab-item} Target ScyllaCluster +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: target + namespace: scylla +spec: + agentVersion: 3.2.5 + version: 5.4.1 + developerMode: true + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 1 + storage: + capacity: 1Gi + resources: + limits: + cpu: 1 + memory: 1Gi +``` +::: +:::: + +Make sure your target cluster is already registered in Scylla Manager. To get a list of all registered clusters, execute the following command: +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool cluster list ++--------------------------------------+---------------------------------------+---------+-----------------+ +| ID | Name | Port | CQL credentials | ++--------------------------------------+---------------------------------------+---------+-----------------+ +| af1dd5cd-0406-4974-949f-dc9842980080 | scylla/target | default | set | +| ebd82268-efb7-407e-a540-3619ae053778 | scylla/source | default | set | ++--------------------------------------+---------------------------------------+---------+-----------------+ +``` + +Identify the tag of a snapshot which you want to restore. To get a list of all available snapshots, execute following command: +```console +kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c --all-clusters -L +``` + +Where: +* `CLUSTER_ID` - the name or ID of a registered cluster with access to `BACKUP_LOCATION`. +* `BACKUP_LOCATION` - the location in which the backup is stored. + +In this example, `BACKUP_LOCATION` is `s3:source-backup`. Use the name of cluster which has access to the backup location for `CLUSTER_ID`. +In this example, it's `scylla/target`. + +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c scylla/target --all-clusters -L s3:source-backup +backup/ff36d7e0-af2e-458c-afe6-868e0f3396b2 +Snapshots: + - sm_20240105115931UTC (409MiB, 1 nodes) +Keyspaces: + - system_schema (15 tables) + - users (9 tables) + +``` + +In the below commands, we are restoring the `sm_20240105115931UTC` snapshot. Replace it with a tag of a snapshot that you want to restore. +Restoring consist of two steps. First, you'll restore the schema, and then the data. +To restore schema, create a restore task manually on target ScyllaCluster by executing following command: +```console +kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c -L -T --restore-schema +``` + +Where: +* `CLUSTER_ID` - a name or ID of a cluster you want to restore into. +* `BACKUP_LOCATION` - the location in which the backup is stored. +* `SNAPSHOT_TAG` - a tag of a snapshot that you want to restore. + +When the task is created, the command will output the ID of a restore task. +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-schema +restore/57228c52-7cf6-4271-8c8d-d446ff160747 +``` + +Use the following command to check progress of the restore task: +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/57228c52-7cf6-4271-8c8d-d446ff160747 +Restore progress +Run: 0dd20cdf-abc4-11ee-951c-6e7993cf42ed +Status: DONE - restart required (see restore docs) +Start time: 05 Jan 24 12:15:02 UTC +End time: 05 Jan 24 12:15:09 UTC +Duration: 6s +Progress: 100% | 100% +Snapshot Tag: sm_20240105115931UTC + ++---------------+-------------+----------+----------+------------+--------+ +| Keyspace | Progress | Size | Success | Downloaded | Failed | ++---------------+-------------+----------+----------+------------+--------+ +| system_schema | 100% | 100% | 214.150k | 214.150k | 214.150k | 0 | ++---------------+-------------+----------+----------+------------+--------+ +``` + +As suggested in the progress output, you will need to execute a rolling restart of the ScyllaCluster. +```console +kubectl patch scyllacluster target --type merge -p '{"spec": {"forceRedeploymentReason": "schema restored"}}' +``` + +Use the following commands to wait until restart is finished: +```console +$ kubectl wait --for='condition=Progressing=False' -n scylla scyllaclusters.scylla.scylladb.com/target +scyllacluster.scylla.scylladb.com/target condition met + +$ kubectl wait --for='condition=Degraded=False' -n scylla scyllaclusters.scylla.scylladb.com/target +scyllacluster.scylla.scylladb.com/target condition met + +$ kubectl wait --for='condition=Available=True' -n scylla scyllaclusters.scylla.scylladb.com/target +scyllacluster.scylla.scylladb.com/target condition met +``` + +To restore the tables content, create a restore task manually on target ScyllaCluster by executing the following command: +```console +kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c -L -T --restore-tables +``` + +Where: +* `CLUSTER_ID` - a name or ID of a cluster you want to restore into. +* `BACKUP_LOCATION` - the location in which the backup is stored. +* `SNAPSHOT_TAG` - a tag of a snapshot that you want to restore. + +When the task is created, the command will output the ID of a restore task. +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-tables +restore/63642069-bed5-4def-ba0f-68c49e47ace1 +``` + +Use the following command to check progress of the restore task: +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/63642069-bed5-4def-ba0f-68c49e47ace1 +Restore progress +Run: ab015cef-abc8-11ee-9521-6e7993cf42ed +Status: DONE +Start time: 05 Jan 24 12:48:04 UTC +End time: 05 Jan 24 12:48:15 UTC +Duration: 11s +Progress: 100% | 100% +Snapshot Tag: sm_20240105115931UTC + ++-------------+-------------+--------+---------+------------+--------+ +| Keyspace | Progress | Size | Success | Downloaded | Failed | ++-------------+-------------+--------+---------+------------+--------+ +| users | 100% | 100% | 409MiB | 409MiB | 409MiB | 0 | ++-------------+-------------+--------+---------+------------+--------+ + +Post-restore repair progress +Run: ab015cef-abc8-11ee-9521-6e7993cf42ed +Status: DONE +Start time: 05 Jan 24 12:48:04 UTC +End time: 05 Jan 24 12:48:15 UTC +Duration: 11s +Progress: 100% +Intensity: 1 +Parallel: 0 +Datacenters: + - us-east-1 + ++-------------+--------------+----------+----------+ +| Keyspace | Table | Progress | Duration | ++-------------+--------------+----------+----------+ +| users | users | 100% | 0s | ++-------------+--------------+----------+----------+ + +``` diff --git a/stable/_sources/nodeoperations/scylla-upgrade.md.txt b/stable/_sources/nodeoperations/scylla-upgrade.md.txt new file mode 100644 index 00000000000..d39c9666c5e --- /dev/null +++ b/stable/_sources/nodeoperations/scylla-upgrade.md.txt @@ -0,0 +1,102 @@ +# Upgrading version of Scylla + +To upgrade Scylla version using Operator user have to modify existing ScyllaCluster definition. + +In this example cluster will be upgraded to version `4.4.5`. +```bash +kubectl -n scylla patch ScyllaCluster simple-cluster -p '{"spec":{"version": "4.4.5"}}' --type=merge +``` + +Operator supports two types of version upgrades: +1. Patch upgrade +1. Generic upgrade + + +**Patch upgrade** + +Patch upgrade is executed when only patch version change is detected according to [semantic versioning format](https://semver.org/). +Procedure simply rolls out a restart of whole cluster and upgrades Scylla container image for each node one by one. + +Example: `4.0.0 -> 4.0.1` + +**Generic upgrade** + +Generic upgrades are executed for the non patch version changes. + +Example: `4.0.0 -> 2020.1.0` or `4.0.0 -> 4.1.0` or even `4.0.0 -> nightly` + +User can observe current state of upgrade in ScyllaCluster status. +```bash +kubectl -n scylla describe ScyllaCluster simple-cluster +[...] +Status: + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.1.9 + Upgrade: + Current Node: simple-cluster-us-east-1-us-east-1a-2 + Current Rack: us-east-1a + Data Snapshot Tag: so_data_20201228135002UTC + From Version: 4.1.9 + State: validate_upgrade + System Snapshot Tag: so_system_20201228135002UTC + To Version: 4.2.2 +``` + +Each upgrade begins with taking a snapshot of `system` and `system_schema` keyspaces on all nodes in parallel. +Name of this snapshot tag is saved in upgrade status under `System Snapshot Tag`. + +Before nodes in rack are upgraded, underlying StatefulSet is changed to use `OnDelete` UpgradeStrategy. +This allows Operator have a full control over when Pod image is changed. + +When a node is being upgraded, [maintenance mode](#maintenance-mode) is enabled, then the node is drained and snapshot of all data keyspaces is taken. +Snapshot tag is saved under `Data Snapshot Tag` and is the same for all nodes during the procedure. +Once everything is set up, maintenance mode is disabled and Scylla Pod is deleted. Underlying StatefulSet will bring up a new +Pod with upgraded version. +Once Pod will become ready, data snapshot from this particular node is removed, and Operator moves to next node. + +Once every rack is upgraded, system snapshot is removed from all nodes in parallel and previous StatefulSet UpgradeStrategy is restored. +At this point, all your nodes should be already in desired version. + +Current state of upgrade can be traced using `Current Node`, `Current Rack` and `State` status fields. +* `Current Node` shows which node is being upgraded. +* `Current Rack` displays which rack is being upgraded. +* `State` contain information at which stage upgrade is. + +`State` can have following values: +* `begin_upgrade` - upgrade is starting +* `check_schema_agreement` - Operator waits until all nodes reach schema agreement. It waits for it for 1 minute, prints an error log message and check is retried. +* `create_system_backup` - system keyspaces snapshot is being taken +* `find_next_rack` - Operator finds out which rack must be upgraded next, decision is saved in `Current Rack` +* `upgrade_image_in_pod_spec` - Image and UpgradeStrategy is upgraded in underlying StatefulSet +* `find_next_node` - Operator finds out which node must be upgraded next, decision is saved in `Current Node` +* `enable_maintenance_mode` - maintenance mode is being enabled +* `drain_node` - node is being drained +* `backup_data` - snapshot of data keyspaces is being taken +* `disable_maintenance_mode` - maintenance mode is being disabled +* `delete_pod` - Scylla Pod is being deleted +* `validate_upgrade` - Operator validates if new pod enters Ready state and if Scylla version is upgraded +* `clear_data_backup` - snapshot of data keyspaces is being removed +* `clear_system_backup` - snapshot of system keyspaces is being removed +* `restore_upgrade_strategy` - restore UpgradeStrategy in underlying StatefulSet +* `finish_upgrade` - upgrade cleanup + +**Recovering from upgrade failure** + +Upgrade may get stuck on `validate_upgrade` stage. This happens when Scylla Pod refuses to properly boot up. + +To continue with upgrade, first turn off operator by scaling Operator replicas to zero: +```bash +kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=0 +``` +Then user have to manually resolve issue with Scylla by checking what is the root cause of a failure in Scylla container logs. +If needed data and system keyspaces SSTable snapshots are available on the node. You can check ScyllaCluster status for their names. + +Once issue is resolved and Scylla Pod is up and running (Pod is in Ready state), scale Operator back to two replicas: +```bash +kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=2 +``` + +Operator should continue upgrade process from where it left off. diff --git a/stable/_sources/performance.md.txt b/stable/_sources/performance.md.txt new file mode 100644 index 00000000000..4b0bbd96781 --- /dev/null +++ b/stable/_sources/performance.md.txt @@ -0,0 +1,95 @@ +# Performance tuning + +Scylla Operator 1.6 introduces a new experimental feature allowing users to optimize Kubernetes nodes. + +## Node tuning + +Starting from Operator 1.6, a new CRD called NodeConfig is available, allowing users to target Nodes which should be tuned. +When a Node is supposed to be optimized, the Scylla Operator creates a DaemonSet covering these Nodes. +Nodes matching the provided placement conditions will be subject to tuning. + +Below example NodeConfig tunes nodes having `scylla.scylladb.com/node-type=scylla` label: +``` +apiVersion: scylla.scylladb.com/v1alpha1 +kind: NodeConfig +metadata: + name: cluster +spec: + placement: + nodeSelector: + scylla.scylladb.com/node-type: scylla +``` +For more details about new CRD use: +``` +kubectl explain nodeconfigs.scylla.scylladb.com/v1alpha1 +``` + +For all optimizations we use a Python script available in the Scylla image called perftune. +Perftune executes the performance optmizations like tuning the kernel, network, disk devices, spreading IRQs across CPUs and more. + +Tuning consists of two separate optimizations: common node tuning, and tuning based on Scylla Pods and their resource assignment. +Node tuning is executed immediately. Pod tuning is executed when Scylla Pod lands on the same Node. + +Scylla works most efficently when it's pinned to CPU and not interrupted. +One of the most common causes of context-switching are network interrupts. Packets coming to a node need to be processed, +and this requires CPU shares. + +On K8s we always have at least a couple of processes running on the node: kubelet, kubernetes provider applications, daemons etc. +These processes require CPU shares, so we cannot dedicate entire node processing power to Scylla, we need to leave space for others. +We take advantage of it, and we pin IRQs to CPUs not used by any Scylla Pods exclusively. + +Tuning resources are created in a special namespace called `scylla-operator-node-tuning`. + +The tuning is applied only to pods with `Guaranteed` QoS class. Please double check your ScyllaCluster resource specification +to see if it meets all conditions. + +## Kubernetes tuning + +By default, the kubelet uses the CFS quota to enforce pod CPU limits. +When the node runs many CPU-bound pods, the workload can move around different CPU cores depending on whether the pod +is throttled and which CPU cores are available. +However, kubelet may be configured to assign CPUs exclusively, by setting the CPU manager policy to static. + +Setting up kubelet configuration is provider specific. Please check the docs for your distribution or talk to your +provider. + +Only pods within the [Guaranteed QoS class](https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed)) can take advantage of this option. +When such pod lands on a Node, kubelet will pin them to specific CPUs, and those won't be part of the shared pool. + +In our case there are two requirements each ScyllaCluster must fulfill to receive a Guaranteed QoS class: +* resource request and limits must be equal or only limits have to be provided +* agentResources must be provided and their requests and limits must be equal, or only limits have to be provided + +An example of such a ScyllaCluster that receives a Guaranteed QoS class is below: + +``` +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: guaranteed-cluster + namespace: scylla +spec: + version: 4.5.1 + agentVersion: 2.5.2 + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 3 + storage: + capacity: 500Gi + agentResources: + requests: + cpu: 1 + memory: 1G + limits: + cpu: 1 + memory: 1G + resources: + requests: + cpu: 4 + memory: 16G + limits: + cpu: 4 + memory: 16G +``` \ No newline at end of file diff --git a/stable/_sources/releases.md.txt b/stable/_sources/releases.md.txt new file mode 100644 index 00000000000..ce4fa27b65d --- /dev/null +++ b/stable/_sources/releases.md.txt @@ -0,0 +1,59 @@ +# Releases + +## Schedule +We are aiming to ship a new release approximately every 6 weeks. The following release schedule is only advisory, there are no commitments made to hitting these dates. + +| Release | Code freeze | General availability | +|:-------:|:-----------:|:--------------------:| +| 1.11 | 2023-10-02 | 2023-10-16 | + +## Supported releases +We support the latest 2 releases of the operator to give everyone time to upgrade. + +| Release | General availability | Support ends | +|:-------:|:--------------------:|:---------------:| +| 1.10 | 2023-08-25 | Release of 1.12 | +| 1.9 | 2023-07-04 | Release of 1.11 | +| 1.8 | 2023-01-25 | 2023-08-25 | +| 1.7 | 2022-01-27 | 2023-07-04 | +| 1.6 | 2021-12-03 | 2023-01-25 | +| 1.5 | 2021-09-16 | 2022-01-27 | +| 1.4 | 2021-08-10 | 2021-12-03 | +| 1.3 | 2021-06-17 | 2021-09-16 | +| 1.2 | 2021-05-06 | 2021-08-10 | +| 1.1 | 2021-03-22 | 2021-06-17 | +| 1.0 | 2021-01-21 | 2021-05-06 | + +### Backport policy +Usually, only important bug fixes are eligible for being backported. +This may depend on the situation and assessment of the maintainers. + +## CI/CD +We use [GitHub actions](https://github.com/scylladb/scylla-operator/actions/workflows/go.yaml?query=branch%3Amaster+event%3Apush) for our CI/CD. Every merge to a supported branch, or a creation of a tag will automatically trigger a job to build, test and publish the container image and other artifacts like helm charts. Before we publish any image, it must pass the e2e suite. + +### Automated promotions + +| Git reference | Type | Container image | +| :----------------: | :----: | :--------------------------------------------------: | +| **master** | branch | docker.io/scylladb/scylla-operator:**latest** | +| **vX.Y** | branch | docker.io/scylladb/scylla-operator:**X.Y** | +| **vX.Y.Z** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z** | +| **vX.Y.Z-alpha.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-alpha.N** | +| **vX.Y.Z-beta.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-beta.N** | +| **vX.Y.Z-rc.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-rc.N** | + +### Generally available +GA images aren't build from scratch but rather promoted from an existing release candidates. When we decide a release candidate has the acceptable quality and QA sings it off, the release candidate is promoted to become the GA release. This makes sure the image has exactly the same content and SHA as the tested release candidate. + +## Support matrix + +Support matrix table shows the version requirements for a particular **scylla-operator** version. Be sure to match these requirements, otherwise some functionality will not work. + +| | v1.10 | v1.9 | v1.8 | v1.7 | v1.6 | v1.5 | v1.4 | v1.3 | v1.2 | v1.1 | v1.0 | +|:-----------------:|:----------:|:----------:|:----------:|:-----------------:|:--------------------:|:-----------:|:-----------:|:----------:|:----------:|:----------:|:----------:| +| Kubernetes | `>=1.21` | `>=1.21` | `>=1.21` | `>=1.20 && <1.25` | `>=1.19.10 && <1.25` | `>=1.19.10` | `>=1.19.10` | `>=1.19` | `>=1.19` | `>=1.11` | `>=1.11` | +| CRI API | `v1` | `v1` | `v1alpha2` | `v1alpha2` | `v1alpha2` | | | | | | | +| Scylla OS | `>=5.0` | `>=5.0` | `>=5.0` | `>=4.3` | `>=4.3` | `>=4.3` | `>=4.3` | `>=4.2` | `>=4.2` | `>=4.0` | `>=4.0` | +| Scylla Enterprise | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2020.1` | `>=2020.1` | `>=2020.1` | `>=2020.1` | +| Scylla Manager | `>=2.6` | `>=2.6` | `>=2.6` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | +| Scylla Monitoring | `>=4.0` | `>=4.0` | `>=4.0` | `>=3.0` | `>=3.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | diff --git a/stable/_sources/scylla-cluster-crd.md.txt b/stable/_sources/scylla-cluster-crd.md.txt new file mode 100644 index 00000000000..75d34f1a028 --- /dev/null +++ b/stable/_sources/scylla-cluster-crd.md.txt @@ -0,0 +1,188 @@ +# Scylla Cluster CRD + +Scylla database clusters can be created and configured using the `clusters.scylla.scylladb.com` custom resource definition (CRD). + +Please refer to the the [user guide walk-through](generic.md) for deployment instructions. +This page will explain all the available configuration options on the Scylla CRD. + +## Sample + +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: simple-cluster + namespace: scylla +spec: + version: 2.3.1 + repository: scylladb/scylla + developerMode: true + cpuset: false + automaticOrphanedNodeCleanup: true + repairs: + - name: "weekly us-east-1 repair" + intensity: "2" + interval: "7d" + dc: ["us-east-1"] + backups: + - name: "daily users backup" + rateLimit: ["50"] + location: ["s3:cluster-backups"] + interval: "1d" + keyspace: ["users"] + - name: "weekly full cluster backup" + rateLimit: ["50"] + location: ["s3:cluster-backups"] + interval: "7d" + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 3 + storage: + capacity: 500G + storageClassName: local-raid-disks + resources: + requests: + cpu: 8 + memory: 32Gi + limits: + cpu: 8 + memory: 32Gi + placement: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: failure-domain.beta.kubernetes.io/region + operator: In + values: + - us-east-1 + - key: failure-domain.beta.kubernetes.io/zone + operator: In + values: + - us-east-1a + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule +``` + +## Settings Explanation + +### Cluster Settings + +* `version`: The version of Scylla to use. It is used as the image tag to pull. +* `agentVersion`: The version of Scylla Manager Agent to use. It is used as the image tag to pull. +* `repository`: Optional field. Specifies a custom image repo. If left unset, the official docker hub repo is used (scylladb/scylla). +* `agentRepository`: Optional field. Specifies a custom Scylla Manager Agent image repo. If left unset, the official docker hub repo is used (scylladb/scylla). +* `developerMode`: Optional field. If it's true, then Scylla is started in [developer mode](https://www.scylladb.com/2016/09/13/test-dev-env/). This setting is for shared test/dev environments. +* `cpuset`: Optional field. If it's true, then the operator will start Scylla with cpu pinning for maximum performance. For this to work, you need to set the kubelet to use the [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and only specify limits in resources. +* `automaticOrphanedNodeCleanup`: Optional field. Controls if automatic orphan node cleanup should be performed. +* `alternator`: Optional field. Defines Alternator configuration. + * `port`: Port on which to bind to Alternator API. + * `writeIsolation`: *required* Desired write isolation. +* `genericUpgrade`: Optional field. Defines GenericUpgrade configuration. + * `failureStrategy`: specifies which logic is executed when upgrade failure happens. Currently only `Retry` is supported. + * `pollInterval`: specifies how often upgrade logic polls on state updates. + Increasing this value should lower number of requests sent to the kube-apiserver, but it may affect + overall time spent during upgrade. +* `datacenter`: Datacenter definition. +* `sysctls`: Optional field. Sysctl properties to be applied during initialization. +* `scyllaArgs`: Optional field. Command line argument passed to Scylla container image. Note: not all Scylla versions support it. +* `network`: Optional field. Allows to customize network parameters. + * `hostNetworking`: controls if host networking should be enabled. + * `dnsPolicy`: controls Scylla Pod DNS Policy. See [details](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy). +* `repairs`: Optional field. Repair tasks definitions. See `Scylla Manager settings` for details. +* `backups`: Optional field. Repair tasks definitions. See `Scylla Manager settings` for details. + + +In the Scylla model, each cluster contains datacenters and each datacenter contains racks. At the moment, the operator only supports single datacenter setups. + +### Scylla Manager settings + +Tasks are scheduled only when Scylla Manager is deployed in K8s cluster. + +Repairs: +* `name` - **required** - human readable name of the task. It must be unique across all tasks. +* `startDate` - specifies the task start date expressed in the RFC3339 format or `now[+duration]`, e.g. `now+3d2h10m`, +valid units are d, h, m, s (default "now"). +* `interval` - Optional field. Task schedule interval e.g. `3d2h10m`, valid units are d, h, m, s (default "0"). +* `numRetries` - Optional field. The number of times a scheduled task will retry to run before failing (default 3). +* `dc` - Optional field. A list of datacenter glob patterns, e.g. `["dc1", "!otherdc*"]` used to specify the DCs to include or exclude from backup. +* `failFast` - Optional field. Stop repair on first error. +* `intensity` - Optional field. Specifies how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. + If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). + Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. + Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. + For Scylla clusters that **do not support row-level repair**, intensity can be a decimal between (0,1). + In that case it specifies percent of shards that can be repaired in parallel on a repair master node. + For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1. + **Intensity is a number passed as string due to lack of support for float values in k8s controller runtime** +* `parallel` - Optional field. Specifies the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). + Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. + The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. + The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2. +* `keyspace` - Optional field. A list of keyspace/tables glob patterns, e.g. `["keyspace", "!keyspace.table_prefix_*"]` +used to include or exclude keyspaces from repair. +* `smallTableThreshold` - Optional field. Enable small table optimization for tables of size lower than given threshold. +Supported units `[B, MiB, GiB, TiB]` (default `"1GiB"`). + +Backups: + +* `name` - **required** - human readable name of the task. It must be unique across all tasks. +* `startDate` - Optional field. Specifies the task start date expressed in the RFC3339 format or `now[+duration]`, e.g. `now+3d2h10m`, +valid units are d, h, m, s (default "now"). +* `interval` - Optional field. task schedule interval e.g. `3d2h10m`, valid units are d, h, m, s (default "0"). +* `numRetries` - Optional field. the number of times a scheduled task will retry to run before failing (default 3). +* `dc` - Optional field. A list of datacenter glob patterns, e.g. `["dc1","!otherdc*"]` used to specify the DCs to include or exclude from backup. +* `keyspace` - Optional field. A list of keyspace/tables glob patterns, e.g. `["keyspace","!keyspace.table_prefix_*"]` used to include or exclude keyspaces from backup. +* `location` - Optional field. A list of backup locations in the format `[:]:` ex. `s3:my-bucket`. +The `:` part is optional and is only needed when different datacenters are being used to upload data to different locations. +`` Optional field. must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. +The only supported storage at the moment are `s3` and `gcs`. +* `rateLimit` - Optional field. A list of megabytes (MiB) per second rate limits expressed in the format `[:]`. +The `:` part is optional and only needed when different datacenters need different upload limits. +Set to 0 for no limit (default 100). +* `retention` - Optional field. The number of backups which are to be stored (default 3). +* `snapshotParallel` - Optional field. A list of snapshot parallelism limits in the format `[:]`. +The `:` part is optional and allows for specifying different limits in selected datacenters. +If The `:` part is not set, the limit is global (e.g. `["dc1:2,5"]`) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters. +* `uploadParallel` - Optional field. A list of upload parallelism limits in the format `[:]`. +The `:` part is optional and allows for specifying different limits in selected datacenters. +If The `:` part is not set the limit is global (e.g. `["dc1:2,5"]`) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters. + + +### Datacenter Settings + +* `name`: Name of the datacenter. Usually, a datacenter corresponds to a region. +* `racks`: List of racks for the specific datacenter. + +### Rack Settings + +* `name`: Name of the rack. Usually, a rack corresponds to an availability zone. +* `members`: Number of Scylla members for the specific rack. (In Scylla documentation, they are called nodes. We don't call them nodes to avoid confusion as a Scylla Node corresponds to a Kubernetes Pod, not a Kubernetes Node). +* `storage`: Defines the specs of the underlying storage. + * `capacity`: Capacity of the PersistentVolume to request. + * `storageClassName`: Optional field. [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) of PersistentVolume to request. +* `resources`: Defines the CPU and RAM resources for the Scylla Pods. + * `requests`: The minimum amount of resources needed to run a Scylla container. + * `cpu`: CPU requests. + * `memory`: RAM requests. + * `limits`: The maximum amount of resources that can be used by a Scylla container. + * `cpu`: CPU limits. + * `memory`: RAM limits. +* `agentResources`: Optional field. Defines the CPU and RAM resources for the Scylla Manager Agent container. See `resources` for details. +* `volumes`: Optional field. Defines volumes available in Scylla Pod. See [details](https://kubernetes.io/docs/concepts/storage/volumes/). +* `volumeMounts`: Optional field. Defines which volumes will be attached to Scylla container. +* `agentVolumeMounts`: Optional field. Defines which volumes will be attached to Agent container. +* `scyllaConfig`: Optional field. name of custom config map which will be merged with Scylla config. +* `scyllaAgentConfig`: Optional field. name of custom secret which will be merged with Scylla Manager Agent config. +* `placement`: Optional field. Defines the placement of Scylla Pods. Has the following subfields: + * [`nodeAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature) + * [`podAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature) + * [`podAntiAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature) + * [`tolerations`](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration) diff --git a/stable/_sources/support/index.rst.txt b/stable/_sources/support/index.rst.txt new file mode 100644 index 00000000000..9c623218acb --- /dev/null +++ b/stable/_sources/support/index.rst.txt @@ -0,0 +1,12 @@ +========================================================== +Support +========================================================== + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + overview + known-issues + troubleshooting/index + must-gather diff --git a/stable/_sources/support/known-issues.md.txt b/stable/_sources/support/known-issues.md.txt new file mode 100644 index 00000000000..1af3a7bfdd1 --- /dev/null +++ b/stable/_sources/support/known-issues.md.txt @@ -0,0 +1,14 @@ +# Known issues + +### Scylla Manager does not boot up on Minikube + +If your Scylla Manager is failing to apply 8th migration (008_*), then apply fix for [TRUNCATE queries](#truncate-queries-does-not-work-on-minikube). + +### TRUNCATE queries does not work on Minikube + +The `TRUNCATE` queries requires [hairpinning](https://en.wikipedia.org/wiki/Hairpinning) to be enabled. On minikube this is disabled by default. + +To fix it execute the following command: +``` +minikube ssh sudo ip link set docker0 promisc on +``` diff --git a/stable/_sources/support/must-gather.md.txt b/stable/_sources/support/must-gather.md.txt new file mode 100644 index 00000000000..7e0089084da --- /dev/null +++ b/stable/_sources/support/must-gather.md.txt @@ -0,0 +1,101 @@ +# Gathering data with must-gather + +`must-gather` is an embedded tool in Scylla Operator that helps collecting all the necessary info when something goes wrong. + +The tool talks to the Kubernetes API, retrieves a predefined set of resources and saves them into a folder in your current directory. +By default, all collected Secrets are censored to avoid sending sensitive data. +That said, you can always review the archive before you attach it to an issue or your support request. + +Given it needs to talk to the Kubernetes API, at the very least, you need to supply the `--kubeconfig` flag with a path to the kubeconfig file for your Kubernetes cluster, or set the `KUBECONFIG` environment variable. + +## Running must-gather + +There is more than one way to run `must-gather`. +Here are some examples of how you can run the tool. + +### Prerequisites + +All examples assume you have exported `KUBECONFIG` environment variable that points to a kubeconfig file on your machine. +If not, you can run this command to export the common default location. +Please make sure such a file exists. + +```bash +export KUBECONFIG=~/.kube/config +ls -l "${KUBECONFIG}" +``` + +:::{note} + There can be slight deviations in the arguments for your container tool, depending on the container runtime, whether you use SELinux or similar factors. + + As an example, the need for the `Z` option on volume mounts depends on whether you use SELinux and what context is applied on your file or directory. + If you get an error mentioning `Error: lsetxattr : operation not supported`, try it without the `Z` option. +::: + +Let's also check whether your kubeconfig uses [external authentication plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins). +You can determine that by running +```bash +kubectl config view --minify +``` +and checking whether it uses an external exec plugin by looking for this pattern (containing the `exec` key) +```yaml +users: +- name: + user: + exec: +``` +If not, you can skip the rest of this section. + +In case your kubeconfig depends on external binaries, you have to take a few extra steps because the external binary won't be available within our container to authenticate the requests. + +Similarly to how Pods are run within Kubernetes, we'll create a dedicated ServiceAccount for must-gather and use it to run the tool. +(When you are done using it, feel free to remove the Kubernetes resources created for that purpose.) + +```bash +kubectl create namespace must-gather +kubectl -n must-gather create serviceaccount must-gather +kubectl create clusterrolebinding must-gather --clusterrole=cluster-admin --serviceaccount=must-gather:must-gather +export MUST_GATHER_TOKEN +MUST_GATHER_TOKEN=$( kubectl -n must-gather create token must-gather --duration=1h ) +kubeconfig=$( mktemp ) +# Create a copy of the existing kubeconfig and +# replace user authentication using yq, or by adjusting the fields manually. +kubectl config view --minify --raw -o yaml | yq -e '.users[0].user = {"token": env(MUST_GATHER_TOKEN)}' > "${kubeconfig}" +KUBECONFIG="${kubeconfig}" +``` + +:::{note} + If you don't have `yq` installed, you can get it at https://github.com/mikefarah/yq/#install or you can replace the user authentication settings manually. +::: + +### Podman +```bash +podman run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro,Z" -v="$( pwd ):/workspace:Z" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig +``` + +### Docker +```bash +docker run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro" -v="$( pwd ):/workspace" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig +``` + +## Limiting must-gather to a particular namespace + +If you are running a large Kubernetes cluster with many ScyllaClusters, it may be useful to limit the collection of ScyllaClusters to a particular namespace. +Unless you hit scale issues, we advise not to use this mode, as sometimes the ScyllaClusters affect other collected resources, like the manager or they form a multi-datacenter. + +```bash +scylla-operator must-gather --namespace="" +``` + +:::{note} + The `--namespace` flag affects only `ScyllaClusters`. + Other resources related to the operator installation or cluster state will still be collected from other namespaces. +::: + +### Collecting every resource in the cluster + +By default, `must-gather` collects only a predefined subset of resources. +You can also request collecting every resource in the Kubernetes API, if the default set wouldn't be enough to debug an issue. + +```bash +scylla-operator must-gather --all-resources +``` diff --git a/stable/_sources/support/overview.md.txt b/stable/_sources/support/overview.md.txt new file mode 100644 index 00000000000..7097438589c --- /dev/null +++ b/stable/_sources/support/overview.md.txt @@ -0,0 +1,14 @@ +# Support overview + +## Get support + +ScyllaDB provides administrators with [paid support](https://www.scylladb.com/product/support/#enterprise-support), including Scylla Operator. + +## Troubleshooting issues + +To learn more about what to do when issues arise, visit our dedicated [troubleshooting section](troubleshooting/index). + +## Gather data about your cluster + +Scylla Operator contains an embedded tool called [must-gather](must-gather.md) that can collect the required information for requesting support or reporting issues. +Support requests and bug reports are required to attach the must-gather archive to help us understand the issue. diff --git a/stable/_sources/support/troubleshooting/index.rst.txt b/stable/_sources/support/troubleshooting/index.rst.txt new file mode 100644 index 00000000000..b83118e6b18 --- /dev/null +++ b/stable/_sources/support/troubleshooting/index.rst.txt @@ -0,0 +1,8 @@ +========================================================== +Troubleshooting +========================================================== + +.. toctree:: + :maxdepth: 2 + + installation diff --git a/stable/_sources/support/troubleshooting/installation.md.txt b/stable/_sources/support/troubleshooting/installation.md.txt new file mode 100644 index 00000000000..b93fcce7b51 --- /dev/null +++ b/stable/_sources/support/troubleshooting/installation.md.txt @@ -0,0 +1,34 @@ +# Troubleshooting installation issues + +## Webhooks +Scylla Operator provides several custom API resources that use webhooks to function properly. + +Unfortunately, it is often the case that user's clusters have modified SDN, that doesn't extend to the control plane, and Kubernetes apiserver is not able to reach the pods that serve the webhook traffic. +Another common case are firewall rules that block the webhook traffic. + +:::{note} + To be called a Kubernetes cluster, clusters are required to pass Kubernetes conformance test suite. + This suite includes tests that require Kubernetes apiserver to be able to reach webhook services. +::: + +:::{note} + Before filing an issue, please make sure your cluster webhook traffic can reach your webhook services, independently of Scylla Operator resources. +::: + +### EKS + +#### Custom CNI +EKS is currently breaking Kubernetes webhooks [when used with custom CNI networking](https://github.com/aws/containers-roadmap/issues/1215). + +:::{note} + We advise you to avoid using such setups and use a conformant Kubernetes cluster that supports webhooks. +::: + +There are some workarounds where you can reconfigure the webhook to use Ingress or hostNetwork instead, but it's beyond a standard configuration that we support and not specific to the Scylla Operator. + +### GKE + +#### Private clusters + +If you use GKE private clusters you need to manually configure the firewall to allow webhook traffic. +You can find more information on how to do that in [GKE private clusters docs](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#add_firewall_rules). diff --git a/stable/_sources/upgrade.md.txt b/stable/_sources/upgrade.md.txt new file mode 100644 index 00000000000..ab14157256b --- /dev/null +++ b/stable/_sources/upgrade.md.txt @@ -0,0 +1,184 @@ +# Upgrade of Scylla Operator + +This page describes Scylla Operator upgrade procedures. +There are two generic update procedures - via Helm and via kubectl. Before upgrading, please check this page to find out +if your target version requires additional upgrade steps. + +## Upgrade via Helm + +Helm doesn't support managing CustomResourceDefinition resources ([#5871](https://github.com/helm/helm/issues/5871), [#7735](https://github.com/helm/helm/issues/7735)) +These are only created on first install and never updated. In order to update them, users have to do it manually. + +Replace `` with the name of your Helm release for Scylla Operator and replace `` with the version number you want to install: +1. Make sure Helm chart repository is up-to-date: + ``` + helm repo add scylla-operator https://storage.googleapis.com/scylla-operator-charts/stable + helm repo update + ``` +2. Update CRD resources. We recommend using `--server-side` flag for `kubectl apply`, if your version supports it. + ``` + tmpdir=$( mktemp -d ) \ + && helm pull scylla-operator/scylla-operator --version --untar --untardir "${tmpdir}" \ + && find "${tmpdir}"/scylla-operator/crds/ -name '*.yaml' -printf '-f=%p ' \ + | xargs kubectl apply + ``` +3. Update Scylla Operator + ``` + helm upgrade --version scylla-operator/scylla-operator + ``` + +## Upgrade via kubectl + +Replace `` with the version number you want to install: + +1. Checkout source code of version you want to use: + ``` + git checkout + ``` +2. Manifests use rolling minor version tag, you may want to pin it to specific version: + ``` + find deploy/operator -name "*.yaml" | xargs sed --follow-symlinks -i -E "s^docker.io/scylladb/scylla-operator:[0-9]+\.[0-9]+^docker.io/scylladb/scylla-operator:^g" + ``` +3. Update Scylla Operator. We recommend using `--server-side` flag for `kubectl apply`, if your version supports it. + ``` + kubectl apply -f deploy/operator + ``` + +--- + +## `v1.2.0` -> `v1.3.0` + +Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure. + +1. Checkout source code of v1.3.0: + ``` + git checkout v1.3.0 + ``` +1. Update Scylla Operator from deploy directory: + ``` + kubectl -n scylla-operator apply -f deploy/operator + ``` +1. Wait until Scylla Operator is up and running: + ``` + kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com + kubectl -n scylla-operator rollout status deployment.apps/scylla-operator + ``` + +## `v1.1.0` -> `v1.2.0` + +1.2.0 release brought a lot of changes to the Scylla Operator deployment process. +To properly update Scylla Operator one must delete old objects and install updated ones. + +Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure. + +1. Checkout source code of v1.2.0: + ``` + git checkout v1.2.0 + ``` +1. Remove old scylla operator namespace - in our case it's called `scylla-operator-system`: + ``` + kubectl delete namespace scylla-operator-system --wait=true + ``` +1. Remove old webhooks: + ``` + kubectl delete MutatingWebhookConfiguration scylla-operator-mutating-webhook-configuration + kubectl delete ValidatingWebhookConfiguration scylla-operator-validating-webhook-configuration + ``` +1. Install Scylla Operator from deploy directory: + ``` + kubectl -n scylla-operator apply -f deploy/operator + ``` +1. Wait until Scylla Operator is up and running: + ``` + kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com + kubectl -n scylla-operator rollout status deployment.apps/scylla-operator + ``` + +## `v1.0.0` -> `v1.1.0` + +During this update we will change probes and image for Scylla Operator. +A new version brings an automation for upgrade of sidecar image, so a rolling restart of managed Scylla clusters is expected. + +1. Get name of StatefulSet managing Scylla Operator + ```shell + kubectl --namespace scylla-operator-system get sts --selector="control-plane=controller-manager" + + NAME READY AGE + scylla-operator-controller-manager 1/1 95m + ``` + +1. Change probes and used container image by applying following patch: + ```yaml + spec: + template: + spec: + containers: + - name: manager + image: docker.io/scylladb/scylla-operator:1.1.0 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + scheme: HTTP + readinessProbe: + $retainKeys: + - httpGet + httpGet: + path: /readyz + port: 8080 + scheme: HTTP + ``` + To apply above patch save it to file (`operator-patch.yaml` for example) and apply to Operator StatefulSet: + ```shell + kubectl -n scylla-operator-system patch sts scylla-operator-controller-manager --patch "$(cat operator-patch.yaml)" + ``` + + +## `v0.3.0` -> `v1.0.0` + +***Note:*** There's an experimental migration procedure available [here](migration.md). + +`v0.3.0` used a very common name as a CRD kind (`Cluster`). In `v1.0.0` this issue was solved by using less common +kind which is easier to disambiguate. (`ScyllaCluster`). +This change is backward incompatible, so Scylla cluster must be turned off and recreated from scratch. +In case you need to preserve your data, refer to backup and restore guide. + +1. Get list of existing Scylla clusters + ``` + kubectl -n scylla get cluster.scylla.scylladb.com + + NAME AGE + simple-cluster 30m + ``` +1. Delete each one of them + + ``` + kubectl -n scylla delete cluster.scylla.scylladb.com simple-cluster + ``` +1. Make sure you're on `v0.3.0` branch + ``` + git checkout v0.3.0 + ``` +1. Delete existing CRD and Operator + ``` + kubectl delete -f examples/generic/operator.yaml + ``` +1. Checkout `v1.0.0` version + ``` + git checkout v1.0.0 + ``` +1. Install new CRD and Scylla Operator + ``` + kubectl apply -f examples/common/operator.yaml + ``` +1. Migrate your existing Scylla Cluster definition. Change `apiVersion` and `kind` from: + ``` + apiVersion: scylla.scylladb.com/v1alpha1 + kind: Cluster + ``` + to: + ``` + apiVersion: scylla.scylladb.com/v1 + kind: ScyllaCluster + ``` +1. Once your cluster definition is ready, use `kubectl apply` to install fresh Scylla cluster. diff --git a/stable/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/stable/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000000..eb19f698afc --- /dev/null +++ b/stable/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/stable/_sphinx_design_static/design-tabs.js b/stable/_sphinx_design_static/design-tabs.js new file mode 100644 index 00000000000..36b38cf0d91 --- /dev/null +++ b/stable/_sphinx_design_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/stable/_static/basic.css b/stable/_static/basic.css new file mode 100644 index 00000000000..30fee9d0f76 --- /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 00000000000..92fad4b5c0b --- /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 00000000000..54b3c463811 --- /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 00000000000..f1916ec7d1b --- /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 00000000000..2ea7ff3e217 --- /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 00000000000..dbe1aaad79c --- /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 00000000000..65eb0a55363 --- /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/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/stable/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000000..eb19f698afc --- /dev/null +++ b/stable/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/stable/_static/design-tabs.js b/stable/_static/design-tabs.js new file mode 100644 index 00000000000..36b38cf0d91 --- /dev/null +++ b/stable/_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/stable/_static/doctools.js b/stable/_static/doctools.js new file mode 100644 index 00000000000..d06a71d7518 --- /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 00000000000..7e4c114f212 --- /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 00000000000..a858a410e4f 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 00000000000..f8520d5b3e4 --- /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 00000000000..f30770c7edd 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 00000000000..aae1708f26f 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 00000000000..6c7484f082f 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 00000000000..5448c7f007b --- /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 00000000000..09107d9520a --- /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 00000000000..1b1fcc83e30 --- /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 00000000000..7c2b4ebae0d --- /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 00000000000..7e93612026b --- /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 00000000000..67ebbc2f38c --- /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 00000000000..e1ce2c1d784 --- /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 00000000000..f4096cbf111 --- /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 00000000000..2a7c6ea0b74 --- /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 00000000000..3afa25c4812 --- /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 00000000000..44eb829cdcb --- /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 00000000000..875e4216707 --- /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 00000000000..8c924698089 --- /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 00000000000..d1162b73e73 --- /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 00000000000..a9069bb6e5c --- /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 00000000000..cfb2318daef --- /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 00000000000..49d809a5df4 --- /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 00000000000..9df3145dd21 --- /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 00000000000..ee804197a0b --- /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 00000000000..5501492f3e0 --- /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 00000000000..97be900b501 --- /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 00000000000..ee1ac26283d --- /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 00000000000..ba5f2118644 --- /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 00000000000..a7eb4b77a42 --- /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 00000000000..38065653675 --- /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 00000000000..37a709f7a8f --- /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 00000000000..702500be409 --- /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 00000000000..e8329c2afee --- /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 00000000000..f0b9c25419c --- /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 00000000000..906e87279c2 --- /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 00000000000..1ef0920d49e --- /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 00000000000..884451270d2 --- /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 00000000000..3094127decf --- /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 00000000000..dcb5916c264 --- /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 00000000000..0e6192a352c --- /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 00000000000..02b4e425beb --- /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 00000000000..e34eb4504f7 --- /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 00000000000..97fa3a0e213 --- /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 00000000000..80b3787f668 --- /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 00000000000..40a3fd5f6f1 --- /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 00000000000..a952b59937d --- /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 00000000000..5b8d47eb157 --- /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 00000000000..60ebab37953 --- /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 00000000000..98c2ea7d5bf --- /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 00000000000..bb7d8d3ea86 --- /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 00000000000..515c1528a2a --- /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 00000000000..d0146fc4972 --- /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 00000000000..5757435085a --- /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 00000000000..74b01db1684 --- /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 00000000000..80c490c7b01 --- /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 00000000000..6e3ab08e792 --- /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 00000000000..c8cbf67c8cf --- /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 00000000000..81aae93eef6 --- /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 00000000000..fc164ea1e77 --- /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 00000000000..bebe9b82742 --- /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 00000000000..4b900bd0c0a --- /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 00000000000..a4228b34e86 --- /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 00000000000..df42b5522ba --- /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 00000000000..2fe54efdbc3 --- /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 00000000000..3e7bcd6d905 --- /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 00000000000..226c44d853c --- /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 00000000000..bf7aa6af840 --- /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 00000000000..08b95a88eda --- /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 00000000000..e8ae088106f --- /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 00000000000..f7547ab9599 --- /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 00000000000..47e56cddcf7 --- /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 00000000000..e4b1d40331b --- /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 00000000000..5e9f5cd4270 --- /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 00000000000..3351e51d23c --- /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 00000000000..5206e58e986 --- /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 00000000000..4fff669cb6f --- /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 00000000000..b5022d7c4dc --- /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 00000000000..769fa0889f8 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 00000000000..7c06d01674a 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 00000000000..d33fddd62f0 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 00000000000..0462f893d5f --- /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 00000000000..a6c6a26fc99 --- /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 00000000000..d0368a7027b 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 00000000000..0cdadaa2167 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 00000000000..e889f4e368e 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 00000000000..a5bce950c25 --- /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 00000000000..6012e71679b --- /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 00000000000..a1aa0b46ac1 --- /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 00000000000..f64c29e6c7c 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 00000000000..d2f645c645a 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 00000000000..0f53b26afa5 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 00000000000..630f2d90942 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 00000000000..c87abe684d5 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 00000000000..ba52cd223db 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 00000000000..cef08c8654a 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 00000000000..75cccbfdf12 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 00000000000..6f10405f218 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 00000000000..e368cae169c 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 00000000000..74ad6695005 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 00000000000..6ba9ed937c9 --- /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 00000000000..48bec7dde32 --- /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 00000000000..956d1dd0e22 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 00000000000..7ee2b043384 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 00000000000..3b2dc8f1a2c 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 00000000000..299e9cb9955 --- /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 00000000000..655a450b2a4 --- /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 00000000000..b28dc857ccf 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 00000000000..09342ac6875 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 00000000000..9b4c613e702 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 00000000000..96dc785298b 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 00000000000..f88598e05ad 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 00000000000..6f0ca146c0d 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 00000000000..b3d0621193f 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 00000000000..b070bb022cb 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 00000000000..6a8b16a6b4e 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 00000000000..f3b8b2984f6 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 00000000000..b38a6fbbe04 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 00000000000..954bf13bc29 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 00000000000..d35a13d380d 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 00000000000..30ea1d901e1 --- /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 00000000000..190a41642ef --- /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 +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Contributing to Scylla Operator

        +
        +

        Prerequisites

        +

        To develop on scylla-operator, your environment must have the following:

        +
          +
        1. Go 1.13

          +
            +
          • Make sure GOPATH is set to GOPATH=$HOME/go.

          • +
          +
        2. +
        3. Kustomize v3.1.0

        4. +
        5. kubebuilder v2.3.1

        6. +
        7. Docker

        8. +
        9. Git client installed

        10. +
        11. Github account

        12. +
        +

        To install all dependencies (Go, kustomize, kubebuilder, dep), simply run:

        +
        ./install-dependencies.sh
        +
        +
        +
        +
        +

        Initial Setup

        +
        +

        Create a Fork

        +

        From your browser navigate to http://github.com/scylladb/scylla-operator and click the “Fork” button.

        +
        +
        +

        Clone Your Fork

        +

        Open a console window and do the following:

        +
        # Create the scylla operator repo path
        +mkdir -p $GOPATH/src/github.com/scylladb
        +
        +# Navigate to the local repo path and clone your fork
        +cd $GOPATH/src/github.com/scylladb
        +
        +# Clone your fork, where <user> is your GitHub account name
        +git clone https://github.com/<user>/scylla-operator.git
        +
        +
        +
        +
        +

        Add Upstream Remote

        +

        First you will need to add the upstream remote to your local git:

        +
        # Add 'upstream' to the list of remotes
        +git remote add upstream https://github.com/scylladb/scylla-operator.git
        +
        +# Verify the remote was added
        +git remote -v
        +
        +
        +

        Now you should have at least origin and upstream remotes. You can also add other remotes to collaborate with other contributors.

        +
        +
        +
        +

        Development

        +

        To add a feature or to make a bug fix, you will need to create a branch in your fork and then submit a pull request (PR) from the branch.

        +
        +

        Building the project

        +

        You can build the project using the Makefile commands:

        +
          +
        • Open the Makefile and change the IMG environment variable to a repository you have access to.

        • +
        • Run make docker-push and wait for the image to be built and uploaded in your repo.

        • +
        +
        +
        +

        Create a Branch

        +

        From a console, create a new branch based on your fork and start working on it:

        +
        # Ensure all your remotes are up to date with the latest
        +git fetch --all
        +
        +# Create a new branch that is based off upstream master.  Give it a simple, but descriptive name.
        +# Generally it will be two to three words separated by dashes and without numbers.
        +git checkout -b feature-name upstream/master
        +
        +
        +

        Now you are ready to make the changes and commit to your branch.

        +
        +
        +

        Updating Your Fork

        +

        During the development lifecycle, you will need to keep up-to-date with the latest upstream master. As others on the team push changes, you will need to rebase your commits on top of the latest. This avoids unnecessary merge commits and keeps the commit history clean.

        +

        Whenever you need to update your local repository, you never want to merge. You always will rebase. Otherwise you will end up with merge commits in the git history. If you have any modified files, you will first have to stash them (git stash save -u "<some description>").

        +
        git fetch --all
        +git rebase upstream/master
        +
        +
        +

        Rebasing is a very powerful feature of Git. You need to understand how it works or else you will risk losing your work. Read about it in the Git documentation, it will be well worth it. In a nutshell, rebasing does the following:

        +
          +
        • “Unwinds” your local commits. Your local commits are removed temporarily from the history.

        • +
        • The latest changes from upstream are added to the history

        • +
        • Your local commits are re-applied one by one

        • +
        • If there are merge conflicts, you will be prompted to fix them before continuing. Read the output closely. It will tell you how to complete the rebase.

        • +
        • When done rebasing, you will see all of your commits in the history.

        • +
        +
        +
        +
        +

        Submitting a Pull Request

        +

        Once you have implemented the feature or bug fix in your branch, you will open a PR to the upstream repo. Before opening the PR ensure you have added unit tests, are passing the integration tests, cleaned your commit history, and have rebased on the latest upstream.

        +

        In order to open a pull request (PR) it is required to be up to date with the latest changes upstream. If other commits are pushed upstream before your PR is merged, you will also need to rebase again before it will be merged.

        +
        +

        Commit History

        +

        To prepare your branch to open a PR, you will need to have the minimal number of logical commits so we can maintain +a clean commit history. Most commonly a PR will include a single commit where all changes are squashed, although +sometimes there will be multiple logical commits.

        +
        # Inspect your commit history to determine if you need to squash commits
        +git log
        +
        +# Rebase the commits and edit, squash, or even reorder them as you determine will keep the history clean.
        +# In this example, the last 5 commits will be opened in the git rebase tool.
        +git rebase -i HEAD~5
        +
        +
        +

        Once your commit history is clean, ensure you have based on the latest upstream before you open the PR.

        +
        +
        +

        Commit messages

        +

        Please make the first line of your commit message a summary of the change that a user (not a developer) of Operator would like to read, +and prefix it with the most relevant directory of the change followed by a colon. +The changelog gets made by looking at just these first lines so make it good!

        +

        If you have more to say about the commit, then enter a blank line and carry on the description. +Remember to say why the change was needed - the commit itself shows what was changed.

        +

        Writing more is better than less. Comparing the behaviour before the change to that after the change is very useful. +Imagine you are writing to yourself in 12 months time when you’ve forgotten everything about what you just did, and you need to get up to speed quickly.

        +

        If the change fixes an issue then write Fixes #1234 in the commit message. +This can be on the subject line if it will fit. If you don’t want to close the associated issue just put #1234 and the change will get linked into the issue.

        +

        Here is an example of a short commit message:

        +
        sidecar: log on reconcile loop - fixes #1234
        +
        +
        +

        And here is an example of a longer one:

        +
        
        +api: now supports host networking (#1234)
        +
        +The operator CRD now has a "network" property that can be used to
        +select host networking as well as setting the apropriate DNS policy.
        +
        +Fixes #1234
        +
        +
        +
        +
        +

        Submitting

        +

        Go to the Scylla Operator github to open the PR. If you have pushed recently, you should see an obvious link to open the PR. If you have not pushed recently, go to the Pull Request tab and select your fork and branch for the PR.

        +

        After the PR is open, you can make changes simply by pushing new commits. Your PR will track the changes in your fork and update automatically.

        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/eks.html b/stable/eks.html new file mode 100644 index 00000000000..fbd375a0086 --- /dev/null +++ b/stable/eks.html @@ -0,0 +1,729 @@ + + + + + + + + + + + + + Deploying Scylla on EKS | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Deploying Scylla on EKS

        +

        This guide is focused on deploying Scylla on EKS with improved performance. +Performance tricks used by the script won’t work with different machine tiers. +It sets up the kubelets on EKS nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

        +

        Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

        +
        +

        TL;DR;

        +

        If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

        +
        # Edit according to your preference
        +EKS_REGION=us-east-1
        +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
        +
        +# From inside the examples/eks folder
        +cd examples/eks
        +./eks.sh -z "$EKS_ZONES" -r "$EKS_REGION"
        +
        +
        +

        After you deploy, see how you can benchmark your cluster with cassandra-stress.

        +
        +
        +

        Walkthrough

        +
        +

        EKS Setup

        +
        +

        Configure environment variables

        +

        First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

        +
        EKS_REGION=us-east-1
        +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
        +CLUSTER_NAME=scylla-demo
        +
        +
        +
        +
        +

        Creating an EKS cluster

        +

        For this guide, we’ll create an EKS cluster with the following:

        +
          +
        • A NodeGroup of 3 i3-2xlarge Nodes, where the Scylla Pods will be deployed. These nodes will only accept pods having scylla-clusters toleration.

        • +
        +
          - name: scylla-pool
        +    instanceType: i3.2xlarge
        +    desiredCapacity: 3
        +    labels:
        +      scylla.scylladb.com/node-type: scylla
        +    taints:
        +      role: "scylla-clusters:NoSchedule"
        +    ssh:
        +      allow: true
        +    kubeletExtraConfig:
        +      cpuManagerPolicy: static
        +
        +
        +
          +
        • A NodeGroup of 4 c4.2xlarge Nodes to deploy cassandra-stress later on. These nodes will only accept pods having cassandra-stress toleration.

        • +
        +
          - name: cassandra-stress-pool
        +    instanceType: c4.2xlarge
        +    desiredCapacity: 4
        +    labels:
        +      pool: "cassandra-stress-pool"
        +    taints:
        +      role: "cassandra-stress:NoSchedule"
        +    ssh:
        +      allow: true
        +
        +
        +
          +
        • A NodeGroup of 1 i3.large Node, where the monitoring stack and operator will be deployed.

        • +
        +
          - name: monitoring-pool
        +    instanceType: i3.large
        +    desiredCapacity: 1
        +    labels:
        +      pool: "monitoring-pool"
        +    ssh:
        +      allow: true
        +
        +
        +
        +
        +
        +

        Prerequisites

        +
        +

        Installing script third party dependencies

        +

        Script requires several dependencies:

        +
          +
        • eksctl - See: https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html

        • +
        • kubectl - See: https://kubernetes.io/docs/tasks/tools/install-kubectl/

        • +
        +
        +
        +
        +

        Deploying ScyllaDB Operator

        +

        Refer to Deploying Scylla on a Kubernetes Cluster in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites.

        +
        +

        Setting up nodes for ScyllaDB

        +

        ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you’ll first need to form a RAID array from those disks. +NodeConfig performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in Performance tuning section of ScyllaDB Operator’s documentation.

        +

        Deploy NodeConfig to let it take care of the above operations:

        +
        kubectl apply --server-side -f examples/eks/nodeconfig-alpha.yaml
        +
        +
        +
        +
        +

        Deploying Local Volume Provisioner

        +

        Afterwards, deploy ScyllaDB’s Local Volume Provisioner, capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays.

        +
        kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/
        +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml
        +
        +
        +
        +
        +
        +

        Deploying ScyllaDB

        +

        Now you can follow the steps described in Deploying Scylla on a Kubernetes Cluster to launch your ScyllaDB cluster in a highly performant environment.

        +
        +

        Accessing the database

        +

        Instructions on how to access the database can also be found in the generic guide.

        +
        +
        +
        +

        Deleting an EKS cluster

        +

        Once you are done with your experiments delete your cluster using the following command:

        +
        eksctl delete cluster "${CLUSTER_NAME}"
        +
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/exposing.html b/stable/exposing.html new file mode 100644 index 00000000000..a898a097898 --- /dev/null +++ b/stable/exposing.html @@ -0,0 +1,875 @@ + + + + + + + + + + + + + Exposing ScyllaCluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Exposing ScyllaCluster

        +

        This document explains how ScyllaDB Operator exposes ScyllaClusters in different network setups. +A ScyllaCluster can be exposed in various network configurations, independently to clients and nodes.

        +
        +

        Note

        +

        ScyllaClusters can be only exposed when the ScyllaDB version used version is >=2023.1 ScyllaDB Enterprise or >=5.2 ScyllaDB Open Source.

        +
        +
        +

        Expose Options

        +

        exposeOptions specifies configuration options for exposing ScyllaCluster’s. +A ScyllaCluster created without any exposeOptions is equivalent to the following:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +     type: ClusterIP
        +    broadcastOptions:
        +      clients:
        +        type: ServiceClusterIP
        +      nodes:
        +        type: ServiceClusterIP
        +
        +
        +

        The following sections cover what every field controls and what the configuration options are.

        +
        +

        Node Service Template

        +

        nodeService serves as a template for a node-dedicated Service managed by the Scylla Operator for each node within a ScyllaCluster. +The properties of the Services depend on the selected type. +Additionally, there’s an option to define custom annotations, incorporated into each node’s Service, +which might be useful for further tweaking the Service properties or related objects.

        +
        +

        Headless Type

        +

        For Headless type, Scylla Operator creates a Headless Service with a selector pointing to the particular node in the ScyllaCluster. +Such Service doesn’t provide any additional IP addresses, and the internal DNS record resolves to the PodIP of a node.

        +

        This type of Service is useful when ScyllaCluster nodes broadcast PodIPs to clients and other nodes.

        +

        Example:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +     type: Headless
        +
        +
        +
        +
        +

        ClusterIP Type

        +

        For ClusterIP type, Scylla Operator creates a ClusterIP Service backed by a specific node in the ScyllaCluster.

        +

        These IP addresses are only routable within the same Kubernetes cluster, so it’s a good fit, if you don’t want to expose them to other networks.

        +

        Example:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +     type: ClusterIP
        +
        +
        +
        +
        +

        LoadBalancer Type

        +

        For the LoadBalancer type, Scylla Operator generates a LoadBalancer Service that directs traffic to a specific node within the ScyllaCluster. +On platforms with support for external load balancers, this Service provisions one. +The accessibility of this load balancer’s address depends on the platform and any customizations made; in some cases it may be reachable from the internal network or public Internet.

        +

        Customizations are usually managed via Service annotations, key-value pairs provided in annotations field are merged into each Service object. +LoadBalancer Services should be configured to pass through entire traffic.
        +For example, to expose LoadBalancer only to internal network use the following annotations:

        +
        + +
        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +     type: LoadBalancer
        +     annotations:
        +       service.beta.kubernetes.io/aws-load-balancer-scheme: internal
        +       service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
        +
        +
        +
        + +
        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +     type: LoadBalancer
        +     annotations:
        +       networking.gke.io/load-balancer-type: Internal
        +
        +
        +
        +
        +

        Check platform-specific documentation regarding LoadBalancer configuration to learn more about available options.

        +

        LoadBalancer Service is a superset of ClusterIP Service, implying that each LoadBalancer Service also contains an allocated ClusterIP. +They can be configured using the following fields, which propagate to every node Service:

        +
          +
        • externalTrafficPolicy

        • +
        • internalTrafficPolicy

        • +
        • loadBalancerClass

        • +
        • allocateLoadBalancerNodePorts

        • +
        +

        Check Kubernetes Service documentation to learn more about these options.

        +

        Example:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +     type: LoadBalancer
        +     loadBalancerClass: my-custom-load-balancer-class
        +
        +
        +
        +
        +
        +
        +

        Broadcast Options

        +

        Broadcast options control what is the source of the address being broadcasted to clients and nodes. +It’s configured independently for clients and nodes because you may want to expose these two types of traffic on different networks. +Using different networks can help manage costs, reliability, latency, security policies or other metrics you care about.

        +
        +

        PodIP Type

        +

        Address broadcasted to clients/nodes is taken from Pod. +By default, the address is taken from Pod’s status.PodIP field. +Because a Pod can use multiple address, you may want to provide source options by specifying podIP.source.

        +

        Example:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    broadcastOptions:
        +       clients:
        +         type: PodIP
        +         podIP:
        +           source: Status
        +
        +
        +
        +
        +

        ServiceClusterIP Type

        +

        Address broadcasted to clients or nodes is taken from spec.ClusterIP field of a node’s dedicated Service.

        +

        In order to configure it, the nodeService template must specify a Service having a ClusterIP assigned.

        +

        Example:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    broadcastOptions:
        +       clients:
        +         type: ServiceClusterIP
        +
        +
        +
        +
        +

        ServiceLoadBalancerIngress Type

        +

        Address broadcasted to clients/nodes is taken from the node dedicated Service, from status.ingress[0].ipAddress or status.ingress[0].hostname field.

        +

        In order to configure it, the nodeService template must specify the LoadBalancer Service.

        +

        Example:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    broadcastOptions:
        +       clients:
        +         type: ServiceLoadBalancerIngress
        +         podIP:
        +           source: Status
        +
        +
        +
        +
        +
        +
        +

        Deployment Examples

        +

        The following section contains several specific examples of various network scenarios and explains how nodes and clients communicate with one another.

        +
        +

        In-cluster only

        +

        ScyllaCluster definition:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +      type: ClusterIP
        +    broadcastOptions:
        +      clients:
        +        type: ServiceClusterIP
        +      nodes:
        +        type: ServiceClusterIP
        +
        +
        +

        Both client and nodes are deployed within the same Kubernetes cluster. +They talk through ClusterIP addresses taken from the Service. +Because ClusterIP Services are only routable within the same Kubernetes cluster, this cluster won’t be reachable from outside.

        +

        ClusterIPs

        +
        +
        +

        In-cluster node-to-node, VPC clients-to-nodes

        +

        ScyllaCluster definition:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +      type: ClusterIP
        +    broadcastOptions:
        +      clients:
        +        type: PodIP
        +      nodes:
        +        type: ServiceClusterIP
        +
        +
        +

        In this scenario, we assume that the Pod IP subnet is routable within a VPC. +Clients within the VPC network can communicate directly with ScyllaCluster nodes using PodIPs. +Nodes communicate with each other exclusively within the same Kubernetes cluster.

        +

        PodIPs

        +
        +
        +

        Multi VPC

        +

        ScyllaCluster definition:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +      type: Headless
        +    broadcastOptions:
        +      clients:
        +        type: PodIP
        +      nodes:
        +        type: PodIP
        +
        +
        +

        In this scenario, we set up two separate Kubernetes clusters in distinct VPCs. +These VPCs are interconnected to facilitate inter-VPC connectivity. +We operate on the assumption that the Pod IP subnet is routable within each VPC.

        +

        Both ScyllaClusters use the same exposeOptions, nodes broadcast their Pod IP addresses, enabling them to establish connections with one another. +****Check other documentation pages to know how to connect two ScyllaClusters into one logical cluster.

        +

        Clients, whether deployed within the same Kubernetes cluster or within a VPC, have the capability to reach nodes using their Pod IPs. +Since there is no requirement for any address other than the Pod IP, the Headless service type is sufficient.

        +

        MultiVPC

        +
        +
        +

        Internet

        +

        ScyllaCluster definition:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +      type: LoadBalancer
        +    broadcastOptions:
        +      clients:
        +        type: ServiceLoadBalancerIngress
        +      nodes:
        +        type: ClusterIP 
        +
        +
        +

        We assume that a Kubernetes cluster has been deployed in a cloud provider environment that supports external load balancers. +By specifying the LoadBalancer type in the nodeService template, the Scylla Operator generates a dedicated LB Service for each node. +The cloud provider then establishes an external load balancer with an internet-accessible address. +ScyllaDB nodes broadcast this external address to clients, enabling drivers to connect and discover other nodes. +Since all ScyllaDB nodes reside within the same Kubernetes cluster, there is no need to route traffic through the internet. +Consequently, the nodes are configured to communicate via ClusterIP, which is also accessible within LoadBalancer Services.

        +

        Internet

        +
        +

        Other more complex scenarios can be built upon these simple ones.

        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/generic.html b/stable/generic.html new file mode 100644 index 00000000000..d1022f71ae7 --- /dev/null +++ b/stable/generic.html @@ -0,0 +1,946 @@ + + + + + + + + + + + + + Deploying Scylla on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Deploying Scylla on a Kubernetes Cluster

        +

        This is a guide to deploy a Scylla Cluster in a generic Kubernetes environment, meaning that Scylla will not be deployed with the ideal performance. +Scylla performs the best when it has fast disks and direct access to the cpu. +This requires some extra setup, which is platform-specific. +For specific configuration and setup, check for details about your particular environment:

        + +
        +

        Prerequisites

        + +
        +
        +

        Running locally

        +

        Running kubernetes locally is a daunting and error prone task. +Fortunately there are ways to make life easier and Minikube makes it a breeze.

        +

        We need to give minikube a little bit more resources than default so start minikube like this:

        +
        minikube start --cpus=6
        +
        +
        +

        Then make kubectl aware of this local installation like this:

        +
        eval $(minikube docker-env)
        +
        +
        +
        +
        +

        Download Scylla Operator

        +

        In this guide you will be using the examples and manifests from Scylla Operator repository, so start off by cloning it to your local machine.

        +
        git clone git@github.com:scylladb/scylla-operator.git
        +cd scylla-operator
        +
        +
        +
        +
        +

        Deploy Cert Manager

        +

        First deploy Cert Manager, you can either follow upsteam instructions or use following command:

        +
        kubectl apply -f examples/common/cert-manager.yaml
        +
        +
        +

        This will install Cert Manager to provision a self-signed certificate.

        +

        Once it’s deployed, wait until Cert Manager is ready:

        +
        kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io
        +kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook
        +
        +
        +
        +
        +

        Deploy Scylla Operator

        +

        Deploy the Scylla Operator using the following commands:

        +
        kubectl apply -f examples/common/operator.yaml
        +
        +
        +

        This will install the operator in namespace scylla-operator. +Wait until it’s ready:

        +
        kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
        +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
        +
        +
        +

        If you want to check the logs of the operator you can do so with:

        +
        kubectl -n scylla-operator logs deployment.apps/scylla-operator
        +
        +
        +
        +
        +

        Create and Initialize a Scylla Cluster

        +

        Now that the operator is running, we can create an instance of a Scylla cluster by creating an instance of the clusters.scylla.scylladb.com resource. +Some of that resource’s values are configurable, so feel free to browse cluster.yaml and tweak the settings to your liking. +Full details for all the configuration options can be found in the Scylla Cluster CRD documentation.

        +

        When you are ready to create a Scylla cluster, simply run:

        +
        kubectl create -f examples/generic/cluster.yaml
        +
        +
        +

        We can verify that a Kubernetes object has been created that represents our new Scylla cluster with the command below. +This is important because it shows that has successfully extended Kubernetes to make Scylla clusters a first class citizen in the Kubernetes cloud-native environment.

        +
        kubectl -n scylla get ScyllaCluster
        +
        +
        +

        Checking the pods that are created is as easy as:

        +
        kubectl -n scylla get pods
        +
        +
        +

        The output should be something like:

        +
        NAME                                    READY   STATUS    RESTARTS   AGE
        +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          9m49s
        +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          7m43s
        +simple-cluster-us-east-1-us-east-1a-2   2/2     Running   0          6m46s
        +
        +
        +

        It is important to note that the operator creates these instances according to a pattern. +This pattern is as follows: CLUSTER_NAME-DATACENTER_NAME-RACK_NAME-INSTANCE_NUMBER as specified in cluster.yaml.

        +

        In the above example we have the following properties:

        +
          +
        • CLUSTER_NAME: simple-cluster

        • +
        • DATACENTER_NAME: us-east-1

        • +
        • RACK_NAME: us-east-1a

        • +
        • INSTANCE_NUMBER: An automatically generated number attached to the pod name.

        • +
        +

        We picked the names to resemble something you can find in a cloud service but this is inconsequential, they can be set to anything you want.

        +

        To check if all the desired members are running, you should see the same number of entries from the following command as the number of members that was specified in cluster.yaml:

        +
        kubectl -n scylla get pod -l app=scylla
        +
        +
        +

        You can also track the state of a Scylla cluster from its status. To check the current status of a Cluster, run:

        +
        kubectl -n scylla describe ScyllaCluster simple-cluster
        +
        +
        +

        Checking the logs of the running scylla instances can be done like this:

        +
        kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 scylla
        +
        +
        +
        +

        Configure host networking

        +

        To squeeze the most out of your deployment it is sometimes necessary to employ host networking. +To enable this the CRD allows for specifying a network parameter as such:

        +
        version: 4.0.0
        +  agentVersion: 2.0.2
        +  cpuset: true
        +  network:
        +    hostNetworking: true
        +
        +
        +

        This will result in hosts network to be used for the Scylla Stateful Set deployment.

        +
        +
        +

        Configure container kernel parameters

        +

        Sometimes it is necessary to run the container with different kernel parameters. +In order to support this, the Scylla Operator defines a cluster property sysctls that is a list of the desired key-value pairs to set.

        +

        For example: To increase the number events available for asynchronous IO processing in the Linux kernel to N set sysctls tofs.aio-max-nr=N.

        +
        spec:
        +  sysctls:
        +  - "fs.aio-max-nr=2097152"
        +
        +
        +
        +
        +

        Deploying Alternator

        +

        The operator is also capable of deploying Alternator instead of the regular Scylla. +This requires a small change in the cluster definition. +Change the cluster.yaml file from this:

        +
        spec:
        +  version: 4.0.0
        +  agentVersion: 2.0.2
        +  developerMode: true
        +  datacenter:
        +    name: us-east-1
        +
        +
        +

        to this:

        +
        spec:
        +  version: 4.0.0
        +  alternator:
        +    port: 8000
        +    writeIsolation: only_rmw_uses_lwt
        +  agentVersion: 2.0.2
        +  developerMode: true
        +  datacenter:
        +    name: us-east-1
        +
        +
        +

        You can specify whichever port you want.

        +

        You must provide desired write isolation, supported values are: “always”, “forbid_rmw”, “only_rmw_uses_lwt”. +Difference between those isolation levels can be found in Scylla Alternator documentation.

        +

        Once this is done the regular CQL ports will no longer be available, the cluster is a pure Alternator cluster.

        +
        +
        +
        +

        Accessing the Database

        +
          +
        • From kubectl:

        • +
        +

        To get a cqlsh shell in your new Cluster:

        +
        kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- cqlsh
        +> DESCRIBE KEYSPACES;
        +
        +
        +
          +
        • From inside a Pod:

        • +
        +

        When you create a new Cluster, automatically creates a Service for the clients to use in order to access the Cluster. +The service’s name follows the convention <cluster-name>-client. +You can see this Service in your cluster by running:

        +
        kubectl -n scylla describe service simple-cluster-client
        +
        +
        +

        Pods running inside the Kubernetes cluster can use this Service to connect to Scylla. +Here’s an example using the Python Driver:

        +
        from cassandra.cluster import Cluster
        +
        +cluster = Cluster(['simple-cluster-client.scylla.svc'])
        +session = cluster.connect()
        +
        +
        +

        If you are running the Alternator you can access the API on the port you specified using plain http.

        +
        +
        +

        Configure Scylla

        +

        The operator can take a ConfigMap and apply it to the scylla.yaml configuration file. +This is done by adding a ConfigMap to Kubernetes and refering to this in the Rack specification. +The ConfigMap is just a file called scylla.yaml that has the properties you want to change in it. +The operator will take the default properties for the rest of the configuration.

        +
          +
        • Create a ConfigMap the default name that the operator uses is scylla-config:

        • +
        +
        kubectl create configmap scylla-config -n scylla --from-file=/path/to/scylla.yaml
        +
        +
        +
          +
        • Wait for the mount to propagate and then restart the cluster:

        • +
        +
        kubectl rollout restart -n scylla statefulset/simple-cluster-us-east-1-us-east-1a
        +
        +
        +
          +
        • The new config should be applied automatically by the operator, check the logs to be sure.

        • +
        +

        Configuring cassandra-rackdc.properties is done by adding the file to the same mount as scylla.yaml.

        +
        kubectl create configmap scylla-config -n scylla --from-file=/tmp/scylla.yaml --from-file=/tmp/cassandra-rackdc.properties -o yaml --dry-run | kubectl replace -f -
        +
        +
        +

        The operator will then apply the overridable properties prefer_local and dc_suffix if they are available in the provided mounted file.

        +
        +

        Note

        +

        If you want to enable authentication, you first need to adjust system_auth keyspace replication factor to the number of nodes in the datacenter via cqlsh. It allows you to ensure that the user’s information is kept highly available for the cluster. If system_auth is not equal to the number of nodes and a node fails, the user whose information is on that node will be denied access. +For production environments only use NetworkTopologyStrategy.

        +
        kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : <replication_factor>};"
        +
        +
        +

        You can read more about enabling authentication in the Enable authentication section of ScyllaDB’s documentation.

        +
        +
        +
        +

        Configure Scylla Manager Agent

        +

        The operator creates a second container for each scylla instance that runs Scylla Manager Agent. +This container serves as a sidecar and it’s the main endpoint for interacting with Scylla API. +The Scylla Manager Agent can be configured with various things such as the security token used to allow access to Scylla API and storage providers for backups.

        +

        To configure the agent you just create a new secret called scylla-agent-config-secret and populate it with the contents in the scylla-manager-agent.yaml file like this:

        +
        kubectl create secret -n scylla generic scylla-agent-config-secret --from-file scylla-manager-agent.yaml
        +
        +
        +

        See Scylla Manager Agent configuration for a complete reference of the Scylla Manager agent config file.

        +
        +

        Scylla Manager Agent auth token

        +

        Operator provisions Agent auth token by copying value from user provided config secret or auto generates it if it’s empty. +To check which value is being used, decode content of <cluster-name>-auth-token secret. +To change it simply remove the secret. Operator will create a new one. To pick up the change in the cluster, initiate a rolling restart.

        +
        +
        +
        +

        Set up monitoring

        +

        To set up monitoring using Prometheus and Grafana follow this guide.

        +
        +
        +

        Scale a ScyllaCluster

        +

        The operator supports adding new nodes to existing racks, adding new racks to the cluster, as well as removing both single nodes and entire racks. To introduce the changes, edit the cluster with:

        +
        kubectl -n scylla edit scyllaclusters.scylla.scylladb.com/simple-cluster
        +
        +
        +
          +
        • To modify the number of nodes in a rack, update the members field of the selected rack to a desired value.

        • +
        • To add a new rack, append it to the .spec.datacenter.racks list. Remember to choose a unique rack name for the new rack.

        • +
        • To remove a rack, first scale it down to zero nodes, and then remove it from .spec.datacenter.racks list.

        • +
        +

        Having edited and saved the yaml, you can check your cluster’s Status and Events to retrieve information about what’s happening:

        +
        kubectl -n scylla describe scyllaclusters.scylla.scylladb.com/simple-cluster
        +
        +
        +
        +

        Note

        +

        If you have configured ScyllaDB with authenticator set to PasswordAuthenticator, you need to manually configure the replication factor of the system_auth keyspace with every scaling operation.

        +
        kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -u <username> -p <password> -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : <new_replication_factor>};"
        +
        +
        +

        It is recommended to set system_auth replication factor to the number of nodes in each datacenter.

        +
        +
        +
        +

        Benchmark with cassandra-stress

        +

        After deploying our cluster along with the monitoring, we can benchmark it using cassandra-stress and see its performance in Grafana. We have a mini cli that generates Kubernetes Jobs that run cassandra-stress against a cluster.

        +
        +

        Because cassandra-stress doesn’t scale well to multiple cores, we use multiple jobs with a small core count for each

        +
        +
        # Run a benchmark with 10 jobs, with 6 cpus and 50.000.000 operations each.
        +# Each Job will throttle throughput to 30.000 ops/sec for a total of 300.000 ops/sec.
        +hack/cass-stress-gen.py --num-jobs=10 --cpu=6 --memory=20G --ops=50000000 --limit=30000
        +kubectl apply -f scripts/cassandra-stress.yaml
        +
        +
        +

        Make sure you set the proper arguments in case you have altered things such as name or namespace.

        +
        ./hack/cass-stress-gen.py -h
        +usage: cass-stress-gen.py [-h] [--num-jobs NUM_JOBS] [--name NAME] [--namespace NAMESPACE] [--scylla-version SCYLLA_VERSION] [--host HOST] [--cpu CPU] [--memory MEMORY] [--ops OPS] [--threads THREADS] [--limit LIMIT]
        +                          [--connections-per-host CONNECTIONS_PER_HOST] [--print-to-stdout] [--nodeselector NODESELECTOR]
        +
        +Generate cassandra-stress job templates for Kubernetes.
        +
        +optional arguments:
        +  -h, --help            show this help message and exit
        +  --num-jobs NUM_JOBS   number of Kubernetes jobs to generate - defaults to 1
        +  --name NAME           name of the generated yaml file - defaults to cassandra-stress
        +  --namespace NAMESPACE
        +                        namespace of the cassandra-stress jobs - defaults to "default"
        +  --scylla-version SCYLLA_VERSION
        +                        version of scylla server to use for cassandra-stress - defaults to 4.0.0
        +  --host HOST           ip or dns name of host to connect to - defaults to scylla-cluster-client.scylla.svc
        +  --cpu CPU             number of cpus that will be used for each job - defaults to 1
        +  --memory MEMORY       memory that will be used for each job in GB, ie 2G - defaults to 2G * cpu
        +  --ops OPS             number of operations for each job - defaults to 10000000
        +  --threads THREADS     number of threads used for each job - defaults to 50 * cpu
        +  --limit LIMIT         rate limit for each job - defaults to no rate-limiting
        +  --connections-per-host CONNECTIONS_PER_HOST
        +                        number of connections per host - defaults to number of cpus
        +  --print-to-stdout     print to stdout instead of writing to a file
        +  --nodeselector NODESELECTOR
        +                        nodeselector limits cassandra-stress pods to certain nodes. Use as a label selector, eg. --nodeselector role=scylla
        +
        +
        +

        While the benchmark is running, open up Grafana and take a look at the monitoring metrics.

        +

        After the Jobs finish, clean them up with:

        +
        kubectl delete -f scripts/cassandra-stress.yaml
        +
        +
        +
        +
        +

        Clean Up

        +

        To clean up all resources associated with this walk-through, you can run the commands below.

        +

        NOTE: this will destroy your database and delete all of its associated data.

        +
        kubectl delete -f examples/generic/cluster.yaml
        +kubectl delete -f examples/common/operator.yaml
        +kubectl delete -f examples/common/cert-manager.yaml
        +
        +
        +
        +
        +

        Troubleshooting

        +

        If the cluster does not come up, the first step would be to examine the operator’s logs:

        +
        kubectl -n scylla-operator logs deployment.apps/scylla-operator
        +
        +
        +

        If everything looks OK in the operator logs, you can also look in the logs for one of the Scylla instances:

        +
        kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/genindex.html b/stable/genindex.html new file mode 100644 index 00000000000..88d430b560f --- /dev/null +++ b/stable/genindex.html @@ -0,0 +1,549 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + + + +
        + + + + + +
        + + +
        + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/gke.html b/stable/gke.html new file mode 100644 index 00000000000..178eee78383 --- /dev/null +++ b/stable/gke.html @@ -0,0 +1,768 @@ + + + + + + + + + + + + + Deploying Scylla on GKE | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Deploying Scylla on GKE

        +

        This guide is focused on deploying Scylla on GKE with maximum performance (without any persistence guarantees). +It sets up the kubelets on GKE nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

        +

        Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

        +
        +

        TL;DR;

        +

        If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

        +
        # Edit according to your preference
        +GCP_USER=$(gcloud config list account --format "value(core.account)")
        +GCP_PROJECT=$(gcloud config list project --format "value(core.project)")
        +GCP_ZONE=us-west1-b
        +
        +# From inside the examples/gke folder
        +cd examples/gke
        +./gke.sh -u "$GCP_USER" -p "$GCP_PROJECT" -z "$GCP_ZONE"
        +
        +# Example:
        +# ./gke.sh -u yanniszark@arrikto.com -p gke-demo-226716 -z us-west1-b
        +
        +
        +
        +

        Warning

        +

        Make sure to pass a ZONE (ex.: us-west1-b) and not a REGION (ex.: us-west1) or it will deploy nodes in each ZONE available in the region.

        +
        +

        After you deploy, see how you can benchmark your cluster with cassandra-stress.

        +
        +
        +

        Walkthrough

        +
        +

        Google Kubernetes Engine Setup

        +
        +

        Configure environment variables

        +

        First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

        +
        GCP_USER=$( gcloud config list account --format "value(core.account)" )
        +GCP_PROJECT=$( gcloud config list project --format "value(core.project)" )
        +GCP_REGION=us-west1
        +GCP_ZONE=us-west1-b
        +CLUSTER_NAME=scylla-demo
        +CLUSTER_VERSION=$( gcloud container get-server-config --zone ${GCP_ZONE} --format "value(validMasterVersions[0])" )
        +
        +
        +
        +
        +

        Creating a GKE cluster

        +

        First we need to change kubelet CPU Manager policy to static by providing a config file. Create file called systemconfig.yaml with the following content:

        +
        kubeletConfig:
        +  cpuManagerPolicy: static
        +
        +
        +

        Then we’ll create a GKE cluster with the following:

        +
          +
        1. A NodePool of 2 n1-standard-8 Nodes, where the operator and the monitoring stack will be deployed. These are generic Nodes and their free capacity can be used for other purposes.

          +
          gcloud container \
          +clusters create "${CLUSTER_NAME}" \
          +--cluster-version "${CLUSTER_VERSION}" \
          +--node-version "${CLUSTER_VERSION}" \
          +--machine-type "n1-standard-8" \
          +--num-nodes "2" \
          +--disk-type "pd-ssd" --disk-size "20" \
          +--image-type "UBUNTU_CONTAINERD" \
          +--system-config-from-file=systemconfig.yaml \
          +--enable-stackdriver-kubernetes \
          +--no-enable-autoupgrade \
          +--no-enable-autorepair
          +
          +
          +
        2. +
        3. A NodePool of 2 n1-standard-32 Nodes to deploy cassandra-stress later on.

          +
          gcloud container --project "${GCP_PROJECT}" \
          +node-pools create "cassandra-stress-pool" \
          +--cluster "${CLUSTER_NAME}" \
          +--zone "${GCP_ZONE}" \
          +--node-version "${CLUSTER_VERSION}" \
          +--machine-type "n1-standard-32" \
          +--num-nodes "2" \
          +--disk-type "pd-ssd" --disk-size "20" \
          +--node-taints role=cassandra-stress:NoSchedule \
          +--image-type "UBUNTU_CONTAINERD" \
          +--no-enable-autoupgrade \
          +--no-enable-autorepair
          +
          +
          +
        4. +
        5. A NodePool of 4 n1-standard-32 Nodes, where the Scylla Pods will be deployed. Each of these Nodes has 8 local NVMe SSDs attached, which are provided as raw block devices. It is important to disable autoupgrade and autorepair. Automatic cluster upgrade or node repair has a hard timeout after which it no longer respect PDBs and force deletes the Compute Engine instances, which also deletes all data on the local SSDs. At this point, it’s better to handle upgrades manually, with more control over the process and error handling.

          +
          gcloud container \
          +node-pools create "scylla-pool" \
          +--cluster "${CLUSTER_NAME}" \
          +--node-version "${CLUSTER_VERSION}" \
          +--machine-type "n1-standard-32" \
          +--num-nodes "4" \
          +--disk-type "pd-ssd" --disk-size "20" \
          +--local-nvme-ssd-block count="8" \
          +--node-taints role=scylla-clusters:NoSchedule \
          +--node-labels scylla.scylladb.com/node-type=scylla \
          +--image-type "UBUNTU_CONTAINERD" \
          +--no-enable-autoupgrade \
          +--no-enable-autorepair
          +
          +
          +
        6. +
        +
        +
        +

        Setting Yourself as cluster-admin

        +
        +

        (By default GKE doesn’t give you the necessary RBAC permissions)

        +
        +

        Get the credentials for your new cluster

        +
        gcloud container clusters get-credentials "${CLUSTER_NAME}" --zone="${GCP_ZONE}"
        +
        +
        +

        Create a ClusterRoleBinding for your user. +In order for this to work you need to have at least permission container.clusterRoleBindings.create. +The easiest way to obtain this permission is to enable the Kubernetes Engine Admin role for your user in the GCP IAM web interface.

        +
        kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user "${GCP_USER}"
        +
        +
        +
        +
        +
        +

        Prerequisites

        +
        +
        +

        Deploying ScyllaDB Operator

        +

        Refer to Deploying Scylla on a Kubernetes Cluster in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites.

        +
        +

        Setting up nodes for ScyllaDB

        +

        ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you’ll first need to form a RAID array from those disks. +NodeConfig performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in Performance tuning section of ScyllaDB Operator’s documentation.

        +

        Deploy NodeConfig to let it take care of the above operations:

        +
        kubectl apply --server-side -f examples/gke/nodeconfig-alpha.yaml
        +
        +
        +
        +
        +

        Deploying Local Volume Provisioner

        +

        Afterwards, deploy ScyllaDB’s Local Volume Provisioner, capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays.

        +
        kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/
        +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml
        +
        +
        +
        +
        +
        +

        Deploy Scylla cluster

        +

        In order for the example to work you need to modify the cluster definition in the following way:

        +
        sed -i "s/<gcp_region>/${GCP_REGION}/g;s/<gcp_zone>/${GCP_ZONE}/g" examples/gke/cluster.yaml
        +
        +
        +

        This will inject your region and zone into the cluster definition so that it matches the kubernetes cluster you just created.

        +
        +
        +

        Deploying ScyllaDB

        +

        Now you can follow the steps described in Deploying Scylla on a Kubernetes Cluster to launch your ScyllaDB cluster in a highly performant environment.

        +
        +

        Accessing the database

        +

        Instructions on how to access the database can also be found in the generic guide.

        +
        +
        +
        +

        Deleting a GKE cluster

        +

        Once you are done with your experiments delete your cluster using the following command:

        +
        gcloud container --project "${GCP_PROJECT}" clusters delete --zone "${GCP_ZONE}" "${CLUSTER_NAME}"
        +
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/helm.html b/stable/helm.html new file mode 100644 index 00000000000..7855be10d9f --- /dev/null +++ b/stable/helm.html @@ -0,0 +1,916 @@ + + + + + + + + + + + + + Deploying Scylla stack using Helm Charts | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Deploying Scylla stack using Helm Charts

        +

        In this example we will install Scylla stack on Kubernetes. This includes the following components:

        +
          +
        • Scylla Operator

        • +
        • Scylla Manager

        • +
        • Scylla

        • +
        +

        We will use Minikube K8s cluster, but this could be any K8s cluster supported by the Scylla Operator.

        +
        +

        Prerequisites

        +
          +
        • Kubernetes 1.16+

        • +
        • Helm 3+

        • +
        +
        +
        +

        TL;DR

        +
        helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
        +helm repo update
        +kubectl apply -f examples/common/cert-manager.yaml 
        +helm install scylla-operator scylla/scylla-operator --create-namespace --namespace scylla-operator
        +helm install scylla-manager scylla/scylla-manager --create-namespace --namespace scylla-manager
        +helm install scylla scylla/scylla --create-namespace --namespace scylla
        +
        +
        +
        +
        +

        Deploy Cert Manager

        +

        This step is optional if you want to use your own certificate. +If you don’t have one, make sure to not disable autogeneration using Scylla Operator Helm Chart.

        +

        First deploy Cert Manager, you can either follow upsteam instructions or use following command:

        +
        kubectl apply -f examples/common/cert-manager.yaml
        +
        +
        +

        Once it’s deployed, wait until all Cert Manager pods will enter into Running state:

        +
        kubectl wait -n cert-manager --for=condition=ready pod -l app=cert-manager --timeout=60s
        +
        +
        +
        +
        +

        Helm Chart repository

        +

        To install Scylla Helm Chart repository execute the following commands:

        +
        helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
        +helm repo update
        +
        +
        +

        Then you can search through repository, it should contain at least three Helm charts:

        +
        helm search repo scylla
        +NAME                   CHART VERSION   APP VERSION     DESCRIPTION                                       
        +scylla/scylla          1.0.1           v1.0.1          Scylla is a close-to-the-hardware rewrite of Ca...
        +scylla/scylla-manager  1.0.1           v1.0.1          Scylla Manager automates database operations.     
        +scylla/scylla-operator 1.0.1           v1.0.1          Scylla Operator is a Kubernetes Operator for ma...
        +
        +
        +

        All these charts should be installable without any need of customizing (defaults are provided). +Although Helm is used for this particular reason, so lets customize them a bit.

        +
        +
        +

        Scylla Operator Chart

        +

        This chart is very simple, most interesting customizable fields are image, resources and webhook. +All others can be looked up in Chart source in Scylla Operator repository.

        +
        +

        image

        +

        Image allows to define which Scylla Operator image will be used. By default it downloads the image from main +Docker Hub repository, using version defined in Helm Chart. +You can also change pullPolicy if default one does not +fullfill your needs. In Kubernetes documentation you +can read more about different pull policies.

        +

        Image URL will be composed based on these fields in follwing pattern: +repository/scylla-operator:tag

        +
        image:
        +  repository: scylladb
        +  pullPolicy: IfNotPresent
        +  tag: ""
        +
        +
        +
        +
        +

        resources

        +

        You can customize how much resources will be allocated for Operator pods via resource field:

        +
        resources:
        +  limits:
        +    cpu: 100m
        +    memory: 128Mi
        +  requests:
        +    cpu: 100m
        +    memory: 32Mi
        +
        +
        +

        To read more about resource specification, follow Kubernetes documentation.

        +
        +
        +

        webhook

        +

        Webhook field allows to decide whether you want to use autogenerated self-signed certificate using Cert Manager or +whether you want to provide your own certificate.

        +

        createSelfSignedCertificate specifies whether a self-signed certificate should be created using Cert Manager +certificateSecretName: name of a secret containing custom certificate.

        +
        webhook:
        +  createSelfSignedCertificate: true
        +  certificateSecretName: ""
        +
        +
        +
        +
        +

        Customization

        +

        You can customize all these fields and others by providing file containing desired values. +Content of this file will overwrite default values.

        +

        You can find an example in Scylla Operator repository under examples/helm/values.operator.yaml

        +
        +
        +

        Installation

        +

        To deploy Scylla Operator using customized values file execute the following:

        +
        helm install scylla-operator scylla/scylla-operator --values examples/helm/values.operator.yaml --create-namespace --namespace scylla-operator
        +
        +
        +
        +
        +
        +

        Scylla Helm Chart

        +

        Scylla Chart allows to customize and deploy Scylla cluster. +By default Scylla Helm charts deploys working Scylla cluster, but of course we can customize it.

        +
        +

        Customization

        +

        Versions of images used in the cluster can be set via scyllaImage and agentImage

        +
        scyllaImage:
        +  repository: scylladb/scylla
        +  tag: 4.3.0
        +
        +agentImage:
        +  repository: scylladb/scylla-manager-agent
        +  tag: 2.2.1
        +
        +
        +

        A minimal Scylla cluster can be expressed as:

        +
        datacenter: us-east-1
        +racks:
        +- name: us-east-1b
        +  members: 2
        +  storage:
        +    capacity: 5G
        +  resources:
        +    limits:
        +      cpu: 1
        +      memory: 1Gi
        +    requests:
        +      cpu: 1
        +      memory: 1Gi
        +
        +
        +

        Above cluster will use 4.3.0 Scylla, 2.2.1 Scylla Manager Agent sidecar and will have a single rack having 2 nodes. +Each node will have a single CPU and 1 GiB of memory.

        +

        For other customizable fields, please refer to ScyllaCluster CRD definition. +CRD Rack Spec and Helm Chart Rack should have the same fields.

        +
        +
        +

        Installation

        +

        To deploy Scylla cluster using customzied values file execute the following command:

        +
        helm install scylla scylla/scylla --values examples/helm/values.cluster.yaml --create-namespace --namespace scylla
        +
        +
        +

        Scylla Operator will provision this cluster on your K8s environment.

        +
        +
        +
        +

        Scylla Manager Helm Chart

        +

        Scylla Manager Chart allows to customize and deploy Scylla Manager in K8s environment. +Scylla Manager consist of two applications (Scylla Manager itself and Scylla Manager Controller) and additional Scylla cluster.

        +

        To read more about Scylla Manager see Manager guide.

        +
        +

        Scylla Manager

        +

        To set version of used Scylla Manager you can use image field:

        +
        image:
        +  repository: scylladb
        +  pullPolicy: IfNotPresent
        +  tag: 2.2.1
        +
        +
        +

        To control how many resources are allocated for Scylla Manager use resource field:

        +
        resources:
        +  limits:
        +    cpu: 500m
        +    memory: 500Mi
        +  requests:
        +    cpu: 500m
        +    memory: 500Mi
        +
        +
        +
        +
        +

        Scylla Manager Controller

        +

        Similarly Scylla Manager Controller image can be customized:

        +
        controllerImage:
        +  repository: scylladb
        +  pullPolicy: IfNotPresent
        +  tag: ""
        +
        +
        +

        And allocated resources:

        +
        controllerResources:
        +  limits:
        +    cpu: 100m
        +    memory: 30Mi
        +  requests:
        +    cpu: 100m
        +    memory: 20Mi
        +
        +
        +
        +
        +

        Scylla

        +

        To customize internal Scylla instance dedicated to Scylla Manager, see guide above customizing Scylla Helm Chart. +It’s definition should land as a scylla field.

        +
        +
        +

        Customization

        +

        All others customizable fields can be looked up in Chart source in Scylla Operator repository.

        +
        +
        +

        Installation

        +

        To deploy Scylla Manager using customized values file execute the following command:

        +
        helm install scylla-manager scylla/scylla-manager --values examples/helm/values.manager.yaml --create-namespace --namespace scylla-manager
        +
        +
        +
        +
        +
        +

        Results

        +

        Scylla need some time to bootstrap all nodes, but after some time you should be ready to roll. It was simple isn’t it? +You can validate if everything was set up correctly by looking at the all resources created in used namespaces.

        +

        Scylla Operator:

        +
        $ kubectl -n scylla-operator get all
        +
        +NAME                                   READY   STATUS    RESTARTS   AGE
        +pod/scylla-operator-5dbcb54f5c-vjm4m   1/1     Running   0          51s
        +pod/scylla-operator-5dbcb54f5c-wfjbw   1/1     Running   0          51s
        +
        +NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
        +service/scylla-operator-webhook   ClusterIP   10.105.207.130   <none>        443/TCP   51s
        +
        +NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
        +deployment.apps/scylla-operator   2/2     2            2           51s
        +
        +NAME                                         DESIRED   CURRENT   READY   AGE
        +replicaset.apps/scylla-operator-5dbcb54f5c   2         2         2       51s
        +
        +
        +

        Operator is running!

        +

        Scylla Manager:

        +
        $ kubectl -n scylla-manager get all 
        +
        +NAME                                             READY   STATUS    RESTARTS   AGE
        +pod/scylla-manager-669db64dd-bcm4v               1/1     Running   0          89s
        +pod/scylla-manager-controller-844ccc56c4-drbth   1/1     Running   0          89s
        +pod/scylla-manager-controller-844ccc56c4-rhwqx   1/1     Running   0          89s
        +
        +NAME                            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
        +service/scylla-manager          ClusterIP   10.105.231.53   <none>        80/TCP,5090/TCP     89s
        +service/scylla-manager-client   ClusterIP   None            <none>        9180/TCP,5090/TCP   89s
        +
        +NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
        +deployment.apps/scylla-manager              1/1     1            1           89s
        +deployment.apps/scylla-manager-controller   2/2     2            2           89s
        +
        +NAME                                                   DESIRED   CURRENT   READY   AGE
        +replicaset.apps/scylla-manager-669db64dd               1         1         1       89s
        +replicaset.apps/scylla-manager-controller-844ccc56c4   2         2         2       89s
        +
        +
        +

        Good to go, ready to serve!

        +

        Scylla itself:

        +
        $ kubectl -n scylla get all        
        +
        +NAME                                READY   STATUS    RESTARTS   AGE
        +pod/scylla-us-east-1-us-east-1b-0   2/2     Running   0          5m58s
        +pod/scylla-us-east-1-us-east-1b-1   2/2     Running   0          4m29s
        +
        +NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
        +service/scylla-client                   ClusterIP   None           <none>        9180/TCP,5090/TCP                                                 5m59s
        +service/scylla-us-east-1-us-east-1b-0   ClusterIP   10.43.149.92   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   5m58s
        +service/scylla-us-east-1-us-east-1b-1   ClusterIP   10.43.49.0     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   4m29s
        +
        +NAME                                           READY   AGE
        +statefulset.apps/scylla-us-east-1-us-east-1b   2/2     5m59s
        +
        +
        +

        Two running nodes, exactly what we were asking for.

        +
        +
        +

        Monitoring

        +

        To spin up a Prometheus monitoring refer to monitoring guide.

        +

        Helm charts can create ServiceMonitors needed to observe Scylla Managger and Scylla. +Both of these Helm Charts allows to specify whether you want to create a ServiceMonitor:

        +
        serviceMonitor:
        +  create: false
        +
        +
        +

        Change create to true and update your current deployment using:

        +
        helm upgrade --install scylla --namespace scylla scylla/scylla -f examples/helm/values.cluster.yaml
        +
        +
        +

        Helm should notice the difference, install the ServiceMonitor, and then Prometheous will be able to scrape metrics.

        +
        +
        +

        Cleanup

        +

        To remove these applications you can simply uninstall them using Helm CLI:

        +
        helm uninstall scylla -n scylla
        +helm uninstall scylla-manager -n scylla-manager
        +helm uninstall scylla-operator -n scylla-operator
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/index.html b/stable/index.html new file mode 100644 index 00000000000..18a76b48cb9 --- /dev/null +++ b/stable/index.html @@ -0,0 +1,596 @@ + + + + + + + + + + + + + Scylla Operator Documentation | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Scylla Operator Documentation

        +
        +
        +

        Scylla Operator is an open source project which helps users of Scylla Open Source and Scylla Enterprise run Scylla on Kubernetes (K8s) +The Scylla operator manages Scylla clusters deployed to Kubernetes and automates tasks related to operating a Scylla cluster, like installation, out and downscale, rolling upgrades.

        +_images/logo.png +

        For the latest status of the project, and reports issue, see the Github Project. Also check out the K8s Operator lesson on Scylla University.

        +

        scylla-operator is a Kubernetes Operator for managing Scylla clusters.

        +

        Currently it supports:

        +
          +
        • Deploying multi-zone clusters

        • +
        • Scaling up or adding new racks

        • +
        • Scaling down

        • +
        • Monitoring with Prometheus and Grafana

        • +
        • Integration with Scylla Manager

        • +
        • Dead node replacement

        • +
        • Version Upgrade

        • +
        • Backup

        • +
        • Repairs

        • +
        • Autohealing

        • +
        +

        Choose a topic to begin:

        + +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/manager.html b/stable/manager.html new file mode 100644 index 00000000000..1cf7971dea9 --- /dev/null +++ b/stable/manager.html @@ -0,0 +1,803 @@ + + + + + + + + + + + + + Deploying Scylla Manager on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Deploying Scylla Manager on a Kubernetes Cluster

        +

        Scylla Manager is a product for database operations automation, +it can schedule tasks such as repairs and backups. +Scylla Manager can manage multiple Scylla clusters and run cluster-wide tasks +in a controlled and predictable way.

        +

        Scylla Manager is available for Scylla Enterprise customers and Scylla Open Source users. +With Scylla Open Source, Scylla Manager is limited to 5 nodes. +See the Scylla Manager Proprietary Software License Agreement for details.

        +
        +

        Prerequisites

        + +
        +
        +

        Architecture

        +

        Scylla Manager in K8s consist of:

        +
          +
        • Dedicated Scylla Cluster

          +

          Scylla Manager persists its state to a Scylla cluster. +Additional small single node cluster is spawned in the Manager namespace.

          +
        • +
        • Scylla Manager Controller

          +

          Main mission of Controller is to watch changes of Scylla Clusters, and synchronize three states.

          +
            +
          1. What user wants - task definition in CRD.

          2. +
          3. What Controller registered - Task name to Task ID mapping - CRD status.

          4. +
          5. Scylla Manager task listing - internal state of Scylla Manager.

          6. +
          +

          When Scylla Cluster CRD is being deployed Controller will register it in Scylla Manager once cluster reaches desired node count. +Once Cluster is fully up and running it will schedule all tasks defined in Cluster CRD. +Controller also supports task updates and unscheduling.

          +
        • +
        • Scylla Manager

          +

          Regular Scylla Manager, the same used in cloud and bare metal deployments.

          +
        • +
        +
        +
        +

        Deploy Scylla Manager

        +

        Deploy the Scylla Manager using the following commands:

        +
        kubectl apply -f examples/common/manager.yaml
        +
        +
        +

        This will install the Scylla Manager in the scylla-manager namespace. +You can check if the Scylla Manager is up and running with:

        +
        kubectl -n scylla-manager get pods
        +NAME                                               READY   STATUS    RESTARTS   AGE
        +scylla-manager-cluster-manager-dc-manager-rack-0   2/2     Running   0          37m
        +scylla-manager-controller-0                        1/1     Running   0          28m
        +scylla-manager-scylla-manager-7bd9f968b9-w25jw     1/1     Running   0          37m
        +
        +
        +

        As you can see there are three pods:

        +
          +
        • scylla-manager-cluster-manager-dc-manager-rack-0 - is a single node Scylla cluster.

        • +
        • scylla-manager-controller-0 - Scylla Manager Controller.

        • +
        • scylla-manager-scylla-manager-7bd9f968b9-w25jw - Scylla Manager.

        • +
        +

        To see if Scylla Manager is fully up and running we can check their logs. +To do this, execute following command:

        +
        kubectl -n scylla-manager logs scylla-manager-controller-0
        +
        +
        +

        The output should be something like:

        +
        {"L":"INFO","T":"2020-09-23T11:25:27.882Z","M":"Scylla Manager Controller started","version":"","build_date":"","commit":"","built_by":"","go_version":"","options":{"Name":"scylla-manager-controller-0","Namespace":"scylla-manager","LogLevel":"debug","ApiAddress":"http://127.0.0.1:5080/api/v1"},"_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
        +{"L":"INFO","T":"2020-09-23T11:25:28.435Z","M":"Registering Components.","_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
        +
        +
        +

        To check logs of Scylla Manager itself, use following command:

        +
        kubectl -n scylla-manager logs scylla-manager-scylla-manager-7bd9f968b9-w25jw
        +
        +
        +

        The output should be something like:

        +
        {"L":"INFO","T":"2020-09-23T11:26:53.238Z","M":"Scylla Manager Server","version":"2.1.2-0.20200816.76cc4dcc","pid":1,"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
        +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Using config","config":{"HTTP":"127.0.0.1:5080","HTTPS":"","TLSCertFile":"/var/lib/scylla-manager/scylla_manager.crt","TLSKeyFile":"/var/lib/scylla-manager/scylla_manager.key","TLSCAFile":"","Prometheus":":56090","PrometheusScrapeInterval":5000000000,"debug":"127.0.0.1:56112","Logger":{"Mode":"stderr","Level":"info","Development":false},"Database":{"Hosts":["scylla-manager-cluster-manager-dc-manager-rack-0.scylla-manager.svc"],"SSL":false,"User":"","Password":"","LocalDC":"","Keyspace":"scylla_manager","MigrateDir":"/etc/scylla-manager/cql","MigrateTimeout":30000000000,"MigrateMaxWaitSchemaAgreement":300000000000,"ReplicationFactor":1,"Timeout":600000000,"TokenAware":true},"SSL":{"CertFile":"","Validate":true,"UserCertFile":"","UserKeyFile":""},"Healthcheck":{"Timeout":250000000,"SSLTimeout":750000000},"Backup":{"DiskSpaceFreeMinPercent":10,"AgeMax":43200000000000},"Repair":{"SegmentsPerRepair":1,"ShardParallelMax":0,"ShardFailedSegmentsMax":100,"PollInterval":200000000,"ErrorBackoff":300000000000,"AgeMax":0,"ShardingIgnoreMsbBits":12}},"config_files":["/mnt/etc/scylla-manager/scylla-manager.yaml"],"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
        +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Checking database connectivity...","_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
        +
        +
        +

        If there are no errors in the logs, let’s spin a Scylla Cluster.

        +
        +
        +

        Cluster registration

        +

        When the Scylla Manager is fully up and running, lets create a regular instance of Scylla cluster.

        +

        See generic tutorial to spawn your cluster.

        +

        Note: If you already have some Scylla Clusters, after installing Manager they should be +automatically registered in Scylla Manager.

        +

        Once cluster reaches desired node count, cluster status will be updated with ID under which it was registered in Manager.

        +
        kubectl -n scylla describe Cluster
        +
        +[...]
        +Status:
        + Manager Id:  d1d532cd-49f2-4c97-9263-25126532803b
        + Racks:
        +   us-east-1a:
        +     Members:        3
        +     Ready Members:  3
        +     Version:        4.0.0
        +
        +
        +

        You can use this ID to talk to Scylla Manager using sctool CLI installed in Scylla Manager Pod. +You can also use Cluster name in namespace/cluster-name format.

        +
        kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
        +
        +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
        +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
        +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
        +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
        +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
        +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
        +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
        +
        +
        +

        Scylla Manager by default registers recurring healhcheck tasks for Agent and for each of the enabled frontends (CQL, Alternator).

        +

        In this task listing we can see CQL and REST healthchecks.

        +
        +
        +

        Task scheduling

        +

        You can either define tasks prior Cluster creation, or for existing Cluster. +Let’s edit already running cluster definition to add repair and backup task.

        +
        kubectl -n scylla edit Cluster simple-cluster
        +
        +
        +

        Add following task definition to Cluster spec:

        +
          repairs:
        +    - name: "users repair"
        +      keyspace: ["users"]
        +      interval: "1d"
        +  backups:
        +    - name: "weekly backup"
        +      location: ["s3:cluster-backups"]
        +      retention: 3
        +      interval: "7d"
        +    - name: "daily backup"
        +      location: ["s3:cluster-backups"]
        +      retention: 7
        +      interval: "1d"
        +
        +
        +

        For full task definition configuration consult Scylla Cluster CRD.

        +

        Note: Scylla Manager Agent must have access to above bucket prior the update in order to schedule backup task. +Consult Scylla Manager documentation for details on how to set it up.

        +

        Scylla Manager Controller will spot this change and will schedule tasks in Scylla Manager.

        +
        kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
        +
        +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
        +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
        +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
        +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
        +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
        +│ backup/275aae7f-c436-4fc8-bcec-479e65fb8372                 │ -L s3:cluster-backups  --retention 3 │ 23 Sep 20 14:28:58 CEST (+7d)  │ NEW    │
        +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
        +│ repair/d4946360-c29d-4bb4-8b9d-619ada495c2a                 │                                      │ 23 Sep 20 14:38:42 CEST        │ NEW    │
        +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
        +
        +
        +

        As you can see, we have two new tasks, weekly recurring backup, and one repair which should start shortly.

        +

        To check progress of run you can use following command:

        +
        kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task progress --cluster d1d532cd-49f2-4c97-9263-25126532803b repair/d4946360-c29d-4bb4-8b9d-619ada495c2a
        +Status:         RUNNING
        +Start time:     23 Sep 20 14:38:42 UTC
        +Duration:       13s
        +Progress:       2.69%
        +Datacenters:
        +  - us-east-1
        ++--------------------+-------+
        +| system_auth        | 8.06% |
        +| system_distributed | 0.00% |
        +| system_traces      | 0.00% |
        ++--------------------+-------+
        +
        +
        +

        Other tasks can be also tracked using the same command, but using different task ID. +Task IDs are present in Cluster Status as well as in task listing.

        +
        +
        +

        Clean Up

        +

        To clean up all resources associated with Scylla Manager, you can run the commands below.

        +

        NOTE: this will destroy your Scylla Manager database and delete all of its associated data.

        +
        kubectl delete -f examples/common/manager.yaml
        +
        +
        +
        +
        +

        Troubleshooting

        +

        Manager is not running

        +

        If the Scylla Manager does not come up, the first step would be to examine the Manager and Controller logs:

        +
        kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-controller
        +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-scylla-manager-7bd9f968b9-w25jw
        +
        +
        +

        My task wasn’t scheduled

        +

        If your task wasn’t scheduled, Cluster status will be updated with error messages for each failed task. +You can also consult Scylla Manager logs.

        +

        Example:

        +

        Following status describes error when backup task cannot be scheduled, due to lack of access to bucket:

        +
        Status:
        +  Backups:
        +    Error:     create backup target: location is not accessible: 10.100.16.62: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.100.16.62 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.107.193.33: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.107.193.33 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.109.197.60: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.109.197.60 and run "scylla-manager-agent check-location -L s3:manager-test --debug"
        +    Id:        00000000-0000-0000-0000-000000000000
        +    Interval:  0
        +    Location:
        +      s3:manager-test
        +    Name:         adhoc backup
        +    Num Retries:  3
        +    Retention:    3
        +    Start Date:   now
        +  Manager Id:     2b9dbe8c-9daa-4703-a66d-c29f63a917c8
        +  Racks:
        +    us-east-1a:
        +      Members:        3
        +      Ready Members:  3
        +      Version:        4.0.0
        +
        +
        +

        Because Controller is infinitely retrying to schedule each defined task, once permission issues will be resolved, +task should appear in task listing and Cluster status.

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/migration.html b/stable/migration.html new file mode 100644 index 00000000000..a132ef53fa0 --- /dev/null +++ b/stable/migration.html @@ -0,0 +1,740 @@ + + + + + + + + + + + + + Version migrations | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Version migrations

        +
        +

        v0.3.0 -> v1.0.0 migration

        +

        v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common kind +which is easier to disambiguate (ScyllaCluster). +This change is backward incompatible, which means manual migration is needed.

        +

        This procedure involves having two CRDs registered at the same time. We will detach Scylla Pods +from Scylla Operator for a short period to ensure that nothing is garbage collected when Scylla Operator is upgraded. +Compared to the upgrade guide where full deletion is requested, this procedure shouldn’t cause downtimes. +Although detaching resources from their controller is considered hacky. This means that you shouldn’t run procedure +out of the box on production. Make sure this procedure works well multiple times on your staging environment first.

        +

        Read the whole procedure and make sure you understand what is going on before executing any of the commands!

        +

        In case of any issues or questions regarding this procedure, you’re welcomed on our Scylla Users Slack +on #kubernetes channel.

        +
        +
        +

        Procedure

        +
          +
        1. Execute this whole procedure for each cluster sequentially. To get a list of existing clusters execute the following

          +
          kubectl -n scylla get cluster.scylla.scylladb.com
          +
          +NAME             AGE
          +simple-cluster   30m
          +
          +
          +

          All below commands will use scylla namespace and simple-cluster as a cluster name.

          +
        2. +
        3. Make sure you’re using v1.0.0 tag:

          +
          git checkout v1.0.0
          +
          +
          +
        4. +
        5. Upgrade your cert-manager to v1.0.0. If you installed it from a static file from this repo, simply execute the following:

          +
           kubectl apply -f examples/common/cert-manager.yaml
          +
          +
          +

          If your cert-manager was installed in another way, follow official instructions on cert-manager website.

          +
        6. +
        7. examples/common/operator.yaml file contains multiple resources. Extract only CustomResourceDefinition to separate file.

        8. +
        9. Install v1.0.0 CRD definition from file created in the previous step:

          +
          kubectl apply -f examples/common/crd.yaml
          +
          +
          +
        10. +
        11. Save your existing simple-cluster Cluster definition to a file:

          +
          kubectl -n scylla get cluster.scylla.scylladb.com simple-cluster -o yaml > existing-cluster.yaml
          +
          +
          +
        12. +
        13. Migrate Kind and ApiVersion to new values using:

          +
          sed -i 's/scylla.scylladb.com\/v1alpha1/scylla.scylladb.com\/v1/g' existing-cluster.yaml
          +sed -i 's/kind: Cluster/kind: ScyllaCluster/g' existing-cluster.yaml
          +
          +
          +
        14. +
        15. Install migrated CRD instance

          +
          kubectl apply -f existing-cluster.yaml
          +
          +
          +

          At this point, we should have two CRDs describing your Scylla cluster, although the new one is not controlled by the Operator.

          +
        16. +
        17. Get UUID of newly created ScyllaCluster resource:

          +
          kubectl -n scylla get ScyllaCluster simple-cluster --template="{{ .metadata.uid }}"
          +
          +12a3678d-8511-4c9c-8a48-fa78d3992694
          +
          +
          +

          Save output UUID somewhere, it will be referred as <new-cluster-uid> in commands below.

          +

          Depending on your shell, you might get additional ‘%’ sign at the end of UUID, make sure to remove it!

          +
        18. +
        19. Upgrade ClusterRole attached to each of the Scylla nodes to grant them permission to lookup Scylla clusters:

          +
          kubectl patch ClusterRole simple-cluster-member --type "json" -p '[{"op":"add","path":"/rules/-","value":{"apiGroups":["scylla.scylladb.com"],"resources":["scyllaclusters"],"verbs":["get"]}}]'
          +
          +
          +

          Amend role name according to your cluster name, it should look like <scylla-cluster-name>-member.

          +
        20. +
        21. Get a list of all Services associated with your cluster. First get list of all services:

          +
           kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
          +
          + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
          + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          109m
          + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
          + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   108m
          + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   106m
          +
          +
          +
          +
        22. +
        23. For each service, change its ownerReference to point to new CRD instance:

          +
           kubectl -n scylla patch svc <cluster-svc-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
          +
          +
          +

          Replace <cluster-svc-name> with Service name, and <new-cluster-uid> with saved UUID from one of the previous steps.

          +
        24. +
        25. Get a list of all Services again to see if none was deleted. Check also “Age” column, it shouldn’t be lower than previous result.

          +
           kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
          +
          + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
          + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          110m
          + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   110m
          + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
          + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   107m
          +
          +
          +
          +
        26. +
        27. Get a list of StatefulSets associated with your cluster:

          +
          kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
          +
          +NAME                                  READY   AGE
          +simple-cluster-us-east-1-us-east-1a   3/3     104m
          +
          +
          +
        28. +
        29. For each StatefulSet from previous step, change its ownerReference to point to new CRD instance.

          +
           kubectl -n scylla patch sts <cluster-sts-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
          +
          +
          +

          Replace <cluster-sts-name> with StatefulSet name, and <new-cluster-uid> with saved UUID from one of the previous steps.

          +
        30. +
        31. Now when all k8s resources bound to Scylla are attached to new CRD, we can remove 0.3.0 Operator and old CRD definition. +Checkout v0.3.0 version, and remove Scylla Operator, and old CRD:

          +
           git checkout v0.3.0
          + kubectl delete -f examples/generic/operator.yaml
          +
          +
          +
        32. +
        33. Checkout v1.0.0, and install upgraded Scylla Operator:

          +
           git checkout v1.0.0
          + kubectl apply -f examples/common/operator.yaml
          +
          +
          +
        34. +
        35. Wait until Scylla Operator boots up:

          +
           kubectl -n scylla-operator-system wait --for=condition=ready pod --all --timeout=600s
          +
          +
          +
        36. +
        37. Get a list of StatefulSets associated with your cluster:

          +
          kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
          +
          +NAME                                  READY   AGE
          +simple-cluster-us-east-1-us-east-1a   3/3     104m
          +
          +
          +
        38. +
        39. For each StatefulSet from previous step, change its sidecar container image to v1.0.0, and wait until change will be propagated. This step will initiate a rolling restart of pods one by one.

          +
          kubectl -n scylla patch sts <cluster-sts> --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/initContainers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
          +kubectl -n scylla rollout status sts <cluster-sts>
          +
          +
          +

          Replace <cluster-sts-name> with StatefulSet name.

          +
        40. +
        41. If you’re using Scylla Manager, bump Scylla Manager Controller image to v1.0.0

          +
           kubectl -n scylla-manager-system patch sts scylla-manager-controller --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
          +
          +
          +
        42. +
        43. Your Scylla cluster is now migrated to v1.0.0.

        44. +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/monitoring.html b/stable/monitoring.html new file mode 100644 index 00000000000..0cea9e153a2 --- /dev/null +++ b/stable/monitoring.html @@ -0,0 +1,785 @@ + + + + + + + + + + + + + Monitoring | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Monitoring

        +

        Scylla Operator 1.8 introduced a new API resource ScyllaDBMonitoring, allowing users to deploy a managed monitoring +setup for their Scylla Clusters.

        +
        apiVersion: scylla.scylladb.com/v1alpha1
        +kind: ScyllaDBMonitoring
        +metadata:
        +  name: example
        +spec:
        +  type: Platform
        +  endpointsSelector:
        +    matchLabels:
        +      app.kubernetes.io/name: scylla
        +      scylla-operator.scylladb.com/scylla-service-type: identity
        +      scylla/cluster: replace-with-your-scyllacluster-name
        +  components:
        +    prometheus:
        +      storage:
        +        volumeClaimTemplate:
        +          spec:
        +            resources:
        +              requests:
        +                storage: 1Gi
        +    grafana:
        +      exposeOptions:
        +        webInterface:
        +          ingress:
        +            ingressClassName: haproxy
        +            dnsDomains:
        +            - test-grafana.test.svc.cluster.local
        +            annotations:
        +              haproxy-ingress.github.io/ssl-passthrough: "true"
        +
        +
        +

        For details, refer to the below command:

        +
        $ kubectl explain scylladbmonitorings.scylla.scylladb.com/v1alpha1
        +
        +
        +
        +

        Deploy managed monitoring

        +

        Note: as of v1.8, ScyllaDBMonitoring is experimental. The API is currently in version v1alpha1 and may change in future versions.

        +
        +

        Requirements

        +

        Before you can set up your ScyllaDB monitoring, you need Scylla Operator already installed in your Kubernetes cluster. +For more information on how to deploy Scylla Operator, see:

        + +

        The above example of the monitoring setup also makes use of HAProxy Ingress and Prometheus Operator. +You can deploy them in your Kubernetes cluster using the provided third party examples. If you already have them deployed +in your cluster, you can skip the below steps.

        +
        +

        Deploy Prometheus Operator

        +

        Deploy Prometheus Operator using kubectl:

        +
        $ kubectl -n prometheus-operator apply --server-side -f ./examples/third-party/prometheus-operator
        +
        +
        +
        +
        Wait for Prometheus Operator to roll out
        +
        $ kubectl -n prometheus-operator rollout status --timeout=5m deployments.apps/prometheus-operator
        +deployment "prometheus-operator" successfully rolled out
        +
        +
        +
        +
        +
        +

        Deploy HAProxy Ingress

        +

        Deploy HAProxy Ingress using kubectl:

        +
        $ kubectl -n haproxy-ingress apply --server-side -f ./examples/third-party/haproxy-ingress
        +
        +
        +
        +
        Wait for HAProxy Ingress to roll out
        +
        $ kubectl -n haproxy-ingress rollout status --timeout=5m deployments.apps/haproxy-ingress
        +deployment "haproxy-ingress" successfully rolled out
        +
        +
        +
        +
        +
        +
        +

        Deploy ScyllaDBMonitoring

        +

        First, update the endpointsSelector in examples/monitoring/v1alpha1/scylladbmonitoring.yaml with a label +matching your ScyllaCluster instance name.

        +

        Deploy the monitoring setup using kubectl:

        +
        $ kubectl -n scylla apply --server-side -f ./examples/monitoring/v1alpha1/scylladbmonitoring.yaml
        +
        +
        +

        Scylla Operator will notice the new ScyllaDBMonitoring object, and it will reconcile all necessary resources.

        +
        +

        Wait for ScyllaDBMonitoring to roll out

        +
        $ kubectl wait --for='condition=Progressing=False' scylladbmonitorings.scylla.scylladb.com/example
        +scylladbmonitoring.scylla.scylladb.com/example condition met
        +
        +$ kubectl wait --for='condition=Degraded=False' scylladbmonitorings.scylla.scylladb.com/example
        +scylladbmonitoring.scylla.scylladb.com/example condition met
        +
        +$ kubectl wait --for='condition=Available=True' scylladbmonitorings.scylla.scylladb.com/example
        +scylladbmonitoring.scylla.scylladb.com/example condition met
        +
        +
        +
        +
        +

        Wait for Prometheus to roll out

        +
        $ kubectl rollout status --timeout=5m statefulset.apps/prometheus-example
        +statefulset rolling update complete 1 pods at revision prometheus-example-65b89d55bb...
        +
        +
        +
        +
        +

        Wait for Grafana to roll out

        +
        $ kubectl rollout status --timeout=5m deployments.apps/example-grafana
        +deployment "example-grafana" successfully rolled out
        +
        +
        +
        +
        +
        +

        Accessing Grafana

        +

        For accessing Grafana service from outside the Kubernetes cluster we recommend using an Ingress, although there are many other ways to do so. +When using Ingress, what matters is to direct your packets to the ingress controller Service/Pods and have the correct TLS SNI field set by the caller when reaching out to the service, so it is routed properly, and your client can successfully validate the grafana serving certificate. +This is easier when you are using a real DNS domain that resolves to your Ingress controller’s IP address but most clients and tools allow setting the SNI field manually.

        +
        +
        +

        Prerequisites

        +

        To access Grafana, you first need to collect the serving CA and the credentials.

        +
        $ GRAFANA_SERVING_CERT="$( kubectl -n scylla get secret/example-grafana-serving-ca --template '{{ index .data "tls.crt" }}' | base64 -d )"
        +$ GRAFANA_USER="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "username" }}' | base64 -d )"
        +$ GRAFANA_PASSWORD="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "password" }}' | base64 -d )"
        +
        +
        +
        +
        +

        Connecting through Ingress using a resolvable domain

        +

        In production clusters, the Ingress controller and appropriate DNS records should be set up already. Often there is already a generic wildcard record like *.app.mydomain pointing to the Ingress controller’s external IP. For custom service domains, it is usually a CNAME pointing to the Ingress controller’s A record.

        +

        Note: The ScyllaDBMonitoring example creates an Ingress object with test-grafana.test.svc.cluster.local DNS domain that you should adjust to your domain. Below examples use example-grafana.apps.mydomain.

        +

        Note: To test a resolvable domain from your machine without creating DNS records, you can adjust /etc/hosts or similar.

        +
        $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://example-grafana.apps.mydomain" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
        +200
        +
        +
        +
        +
        +

        Connecting through Ingress using an unresolvable domain

        +

        To connect to an Ingress without a resolvable domain you first need to find out your Ingress controller’s IP that can be resolved externally. Again, there are many ways to do so beyond the below examples.

        +

        Unless stated otherwise, we assume your Ingress is running on port 443.

        +
        $ INGRESS_PORT=443
        +
        +
        +
        +

        Variants

        +
        +
        Ingress ExternalIP
        +

        When you are running in a real cluster there is usually a cloud LoadBalancer or a bare metal alternative providing you with an externally reachable IP address.

        +
        $ INGRESS_IP="$( kubectl -n=haproxy-ingress get service/haproxy-ingress --template='{{ ( index .status.loadBalancer.ingress 0 ).ip }}' )"
        +
        +
        +
        +
        +
        Ingress NodePort
        +

        NodePort is slightly less convenient, but it’s available in development clusters as well.

        +
        $ INGRESS_IP="$( kubectl get nodes --template='{{ $internal_ip := "" }}{{ $external_ip := "" }}{{ range ( index .items 0 ).status.addresses }}{{ if eq .type "InternalIP" }}{{ $internal_ip = .address }}{{ else if eq .type "ExternalIP" }}{{ $external_ip = .address }}{{ end }}{{ end }}{{ if $external_ip }}{{ $external_ip }}{{ else }}{{ $internal_ip }}{{ end }}' )"
        +$ INGRESS_PORT="$( kubectl -n=haproxy-ingress get services/haproxy-ingress --template='{{ range .spec.ports }}{{ if eq .port 443 }}{{ .nodePort }}{{ end }}{{ end }}' )"
        +
        +
        +
        +
        +
        Connection
        +
        $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://test-grafana.test.svc.cluster.local:${INGRESS_PORT}" --resolve "test-grafana.test.svc.cluster.local:${INGRESS_PORT}:${INGRESS_IP}" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
        +200
        +
        +
        +
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/multidc/eks.html b/stable/multidc/eks.html new file mode 100644 index 00000000000..b8342fb8f2b --- /dev/null +++ b/stable/multidc/eks.html @@ -0,0 +1,769 @@ + + + + + + + + + + + + + Build multiple Amazon EKS clusters with inter-Kubernetes networking | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Build multiple Amazon EKS clusters with inter-Kubernetes networking

        +

        This document describes the process of creating multiple Amazon EKS clusters in different regions, using separate VPCs, and explains the steps necessary for configuring inter-Kubernetes networking between the clusters. +The interconnected clusters can serve as a platform for deploying a multi-datacenter ScyllaDB cluster.

        +

        This guide will walk you through the process of creating and configuring EKS clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference.

        +
        +

        Prerequisites

        +

        To follow the below guide, you first need to install and configure the tools that you will need to create and manage AWS and Kubernetes resources:

        +
          +
        • eksctl – A command line tool for working with EKS clusters.

        • +
        • kubectl – A command line tool for working with Kubernetes clusters.

        • +
        +

        For more information see Getting started with Amazon EKS – eksctl in AWS documentation.

        +
        +
        +

        Create EKS clusters

        +
        +

        Create the first EKS cluster

        +

        Below is the required specification for the first cluster.

        +
        apiVersion: eksctl.io/v1alpha5
        +kind: ClusterConfig
        +
        +metadata:
        +  name: scylladb-us-east-1
        +  region: us-east-1
        +
        +availabilityZones:
        +- us-east-1a
        +- us-east-1b
        +- us-east-1c
        +
        +vpc:
        +  cidr: 10.0.0.0/16
        +
        +nodeGroups:
        +  ...
        +
        +
        +

        Specify the first cluster’s configuration file and save it as cluster-us-east-1.yaml. +Refer to Creating an EKS cluster section of ScyllaDB Operator documentation for the reference of the configuration of node groups.

        +

        To deploy the first cluster, use the below command:

        +
        eksctl create cluster -f=cluster-us-east-1.yaml
        +
        +
        +

        Run the following command to learn the status and VPC ID of the cluster:

        +
        eksctl get cluster --name=scylladb-us-east-1 --region=us-east-1
        +
        +
        +

        You will need to get the cluster’s context for future operations. To do so, use the below command:

        +
        kubectl config current-context
        +
        +
        +

        For any kubectl commands that you will want to run against this cluster, use the --context flag with the value returned by the above command.

        +
        +

        Deploy ScyllaDB Operator

        +

        Once the cluster is ready, refer to Deploying Scylla on a Kubernetes Cluster to deploy the ScyllaDB Operator and its prerequisites.

        +
        +
        +

        Prepare nodes for running ScyllaDB

        +

        Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in Deploying Scylla on EKS in ScyllaDB Operator documentation.

        +
        +
        +
        +

        Create the second EKS cluster

        +

        Below is the required specification for the second cluster. As was the case with the first cluster, the provided values are only exemplary and can be adjusted according to your needs.

        +
        +

        Caution

        +

        It is required that the VPCs of the two EKS clusters have non-overlapping IPv4 network ranges.

        +
        +
        apiVersion: eksctl.io/v1alpha5
        +kind: ClusterConfig
        +
        +metadata:
        +  name: scylladb-us-east-2
        +  region: us-east-2
        +
        +availabilityZones:
        +- us-east-2a
        +- us-east-2b
        +- us-east-2c
        +
        +vpc:
        +  cidr: 172.16.0.0/16
        +
        +nodeGroups:
        +  ...
        +
        +
        +

        Follow analogous steps to create the second EKS cluster and prepare it for running ScyllaDB.

        +
        +
        +
        +

        Configure the network

        +

        The prepared Kubernetes clusters each have a dedicated VPC network. +To be able to route the traffic between the two VPC networks, you need to create a networking connection between them, otherwise known as VPC peering.

        +
        +

        Create VPC peering

        +

        Refer to Create a VPC peering connection in AWS documentation for instructions on creating a VPC peering connection between the two earlier created VPCs.

        +

        In this example, the ID of the created VPC peering connection is pcx-08077dcc008fbbab6.

        +
        +
        +

        Update route tables

        +

        To enable private IPv4 traffic between the instances in the VPC peered network, you need to establish a communication channel by adding a route to the route tables associated with all the subnets associated with the instances for both VPCs. +The destination of the new route in a given route table is the CIDR of the VPC of the other cluster and the target is the ID of the VPC peering connection.

        +

        The following is an example of the route tables that enable communication of instances in two peered VPCs. Each table has a local route and the added route which sends traffic targeted at the other VPC to the peered network connection. The other preconfigured routes are omitted for readability.

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Route tableDestinationTarget
        eksctl-scylladb-us-east-1-cluster/PublicRouteTable10.0.0.0/16local
        172.16.0.0/16pcx-08077dcc008fbbab6
        eksctl-scylladb-us-east-2-cluster/PublicRouteTable172.16.0.0/16local
        10.0.0.0/16pcx-08077dcc008fbbab6
        +

        Refer to Update your route tables for a VPC peering connection in AWS documentation for more information.

        +
        +
        +

        Update security groups

        +

        To allow traffic to flow to and from instances associated with security groups in the peered VPC, you need to update the inbound rules of the VPCs’ shared security groups.

        +

        Below is an example of the inbound rules that to be added to the corresponding security groups of the two VPCs.

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

        Security group name

        Type

        Protocol

        Port range

        Source

        eksctl-scylladb-us-east-1-cluster-ClusterSharedNodeSecurityGroup-TD05V9EVU3B8

        All traffic

        All

        All

        Custom 172.16.0.0/16

        eksctl-scylladb-us-east-2-cluster-ClusterSharedNodeSecurityGroup-1FR9YDLU0VE7M

        All traffic

        All

        All

        Custom 10.0.0.0/16

        +

        The names of the shared security groups of your VPCs should be similar to the ones presented in the example.

        +
        +

        Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters in ScyllaDB Operator documentation for guidance.

        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/multidc/gke.html b/stable/multidc/gke.html new file mode 100644 index 00000000000..0b9eb2c1c0e --- /dev/null +++ b/stable/multidc/gke.html @@ -0,0 +1,739 @@ + + + + + + + + + + + + + Build multiple GKE clusters with inter-Kubernetes networking | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Build multiple GKE clusters with inter-Kubernetes networking

        +

        This document describes the process of creating multiple GKE clusters in a shared VPC and explains the steps necessary for configuring inter-Kubernetes networking between clusters in different regions. +The interconnected clusters can serve as a platform for deploying a Multi Datacenter ScyllaDB cluster.

        +

        This guide will walk you through the process of creating and configuring GKE clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference.

        +
        +

        Prerequisites

        +

        To follow the below guide, you first need to install and configure the following tools that you will need to create and manage GCP and Kubernetes resources:

        +
          +
        • gcloud CLI - Google Cloud Command Line Interface, a command line tool for working with Google Cloud resources and services directly.

        • +
        • kubectl – A command line tool for working with Kubernetes clusters.

        • +
        +

        See Install the Google Cloud CLI in GCP documentation and Install Tools in Kubernetes documentation for reference.

        +
        +
        +

        Create and configure a VPC network

        +

        For the clusters to have inter-Kubernetes networking, you will create a virtual network shared between all the instances, with dedicated subnets for each of the clusters. +To create the subnets manually, create the network in custom subnet mode.

        +
        +

        Create the VPC network

        +

        Run the below command to create the network:

        +
        gcloud compute networks create scylladb --subnet-mode=custom
        +
        +
        +

        With the VPC network created, create a dedicated subnet with secondary CIDR ranges for their Pod and Service pools in each region which the clusters will reside in.

        +
        +
        +

        Create VPC network subnets

        +

        To create a subnet for the first cluster in region us-east1, run the below command:

        +
        gcloud compute networks subnets create scylladb-us-east1 \
        +    --region=us-east1 \
        +    --network=scylladb \
        +    --range=10.0.0.0/20 \
        +    --secondary-range='cluster=10.1.0.0/16,services=10.2.0.0/20'
        +
        +
        +

        To create a subnet for the second cluster in region us-west1, run the below command:

        +
        gcloud compute networks subnets create scylladb-us-west1 \
        +    --region=us-west1 \
        +    --network=scylladb \
        +    --range=172.16.0.0/20 \
        +    --secondary-range='cluster=172.17.0.0/16,services=172.18.0.0/20'
        +
        +
        +
        +

        Caution

        +

        It is required that the IPv4 address ranges of the subnets allocated for the GKE clusters do not overlap.

        +
        +

        Refer to Create a VPC-native cluster and Alias IP ranges in GKE documentation for more information about VPC native clusters and alias IP ranges.

        +
        +
        +
        +

        Create GKE clusters

        +

        With the VPC network created, you will now create two VPC native GKE clusters in dedicated regions.

        +
        +

        Create the first GKE cluster

        +

        Run the following command to create the first GKE cluster in the us-east1 region:

        +
        gcloud container clusters create scylladb-us-east1 \
        +    --location=us-east1-b \
        +    --node-locations='us-east1-b,us-east1-c' \
        +    --machine-type=n1-standard-8 \
        +    --num-nodes=1 \
        +    --disk-type=pd-ssd \
        +    --disk-size=20 \
        +    --image-type=UBUNTU_CONTAINERD \
        +    --no-enable-autoupgrade \
        +    --no-enable-autorepair \
        +    --enable-ip-alias \
        +    --network=scylladb \
        +    --subnetwork=scylladb-us-east1 \
        +    --cluster-secondary-range-name=cluster \
        +    --services-secondary-range-name=services
        +
        +
        +

        Refer to Creating a GKE cluster section of ScyllaDB Operator documentation for more information regarding the configuration and deployment of additional node pools, including the one dedicated for ScyllaDB nodes.

        +

        You will need to get the cluster’s context for future operations. To do so, use the below command:

        +
        kubectl config current-context
        +
        +
        +

        For any kubectl commands that you will want to run against this cluster, use the --context flag with the value returned by the above command.

        +
        +

        Deploy ScyllaDB Operator

        +

        Once the cluster is ready, refer to Deploying Scylla on a Kubernetes Cluster to deploy the ScyllaDB Operator and its prerequisites.

        +
        +
        +

        Prepare nodes for running ScyllaDB

        +

        Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in Deploying Scylla on GKE page of the documentation.

        +
        +
        +
        +

        Create the second GKE cluster

        +

        Run the following command to create the second GKE cluster in the us-west1 region:

        +
        gcloud container clusters create scylladb-us-west1 \
        +    --location=us-west1-b \
        +    --node-locations='us-west1-b,us-west1-c' \
        +    --machine-type=n1-standard-8 \
        +    --num-nodes=1 \
        +    --disk-type=pd-ssd \
        +    --disk-size=20 \
        +    --image-type=UBUNTU_CONTAINERD \
        +    --no-enable-autoupgrade \
        +    --no-enable-autorepair \
        +    --enable-ip-alias \
        +    --network=scylladb \
        +    --subnetwork=scylladb-us-west1 \
        +    --cluster-secondary-range-name=cluster \
        +    --services-secondary-range-name=services
        +
        +
        +

        Follow analogous steps to create the second GKE cluster and prepare it for running ScyllaDB.

        +
        +
        +
        +

        Configure the firewall rules

        +

        When creating a cluster, GKE creates several ingress firewall rules that enable the instances to communicate with each other. +To establish interconnectivity between the two created Kubernetes clusters, you will now add the allocated IPv4 address ranges to their corresponding source address ranges.

        +

        First, retrieve the name of the firewall rule associated with the first cluster, which permits traffic between all Pods on a cluster, as required by the Kubernetes networking model. +The rule name is in the following format: gke-[cluster-name]-[cluster-hash]-all.

        +

        To retrieve it, run the below command:

        +
        gcloud compute firewall-rules list --filter='name~gke-scylladb-us-east1-.*-all'
        +
        +
        +

        The output should resemble the following:

        +
        NAME                                NETWORK   DIRECTION  PRIORITY  ALLOW                     DENY  DISABLED
        +gke-scylladb-us-east1-f17db261-all  scylladb  INGRESS    1000      udp,icmp,esp,ah,sctp,tcp        False
        +
        +
        +

        Modify the rule by updating the rule’s source ranges with the allocated Pod IPv4 address ranges of both clusters:

        +
        gcloud compute firewall-rules update gke-scylladb-us-east1-f17db261-all --source-ranges='10.1.0.0/16,172.17.0.0/16'
        +
        +
        +

        Follow the analogous steps for the other cluster. In this example, its corresponding firewall rule name is gke-scylladb-us-west1-0bb60902-all. To update it, you would run:

        +
        gcloud compute firewall-rules update gke-scylladb-us-west1-0bb60902-all --source-ranges='10.1.0.0/16,172.17.0.0/16'
        +
        +
        +

        Refer to Automatically created firewall rules in GKE documentation for more information.

        +
        +

        Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters in ScyllaDB Operator documentation for guidance.

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/multidc/index.html b/stable/multidc/index.html new file mode 100644 index 00000000000..f1f96bc6f0e --- /dev/null +++ b/stable/multidc/index.html @@ -0,0 +1,580 @@ + + + + + + + + + + + + + Deploying multi-datacenter ScyllaDB clusters in Kubernetes | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Deploying multi-datacenter ScyllaDB clusters in Kubernetes

        +

        Prepare a platform for a multi datacenter ScyllaDB cluster deployment:

        +
        +
        + +

        Deploy a multi-datacenter ScyllaDB cluster in Kubernetes:

        +
        +
        + +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/multidc/multidc.html b/stable/multidc/multidc.html new file mode 100644 index 00000000000..a0e7b2413a6 --- /dev/null +++ b/stable/multidc/multidc.html @@ -0,0 +1,1170 @@ + + + + + + + + + + + + + Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters

        +

        This document describes the process of deploying a Multi Datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters.

        +

        This guide will walk you through the example procedure of deploying two datacenters in distinct regions of a selected cloud provider.

        +
        +

        Note

        +

        This guide is dedicated to deploying multi-datacenter ScyllaDB clusters and does not discuss unrelated configuration options. +For details of ScyllaDB cluster deployments and their configuration, refer to Deploying Scylla on a Kubernetes Cluster in ScyllaDB Operator documentation.

        +
        +
        +

        Prerequisites

        +

        As this document describes the procedure of deploying a Multi Datacenter ScyllaDB cluster, you are expected to have the required infrastructure prepared. +Let’s assume two interconnected Kubernetes clusters, capable of communicating with each other over PodIPs, with each cluster meeting the following requirements:

        +
          +
        • a node pool dedicated to ScyllaDB nodes composed of at least 3 nodes running in different zones (with unique topology.kubernetes.io/zone label), configured to run ScyllaDB, each labeled with scylla.scylladb.com/node-type: scylla

        • +
        • running ScyllaDB Operator and its prerequisites

        • +
        • running a storage provisioner capable of provisioning XFS volumes of StorageClass scylladb-local-xfs in each of the nodes dedicated to ScyllaDB instances

        • +
        +

        You can refer to one of our guides describing the process of preparing such infrastructure:

        + +

        Additionally, to follow the below guide, you need to install and configure the following tools that you will need to manage Kubernetes resources:

        +
          +
        • kubectl – A command line tool for working with Kubernetes clusters.

        • +
        +

        See Install Tools in Kubernetes documentation for reference.

        +
        +
        +

        Multi Datacenter ScyllaDB Cluster

        +

        In v1.11, ScyllaDB Operator introduced support for manual multi-datacenter ScyllaDB cluster deployments.

        +
        +

        Warning

        +

        ScyllaDB Operator only supports manual configuration of multi-datacenter ScyllaDB clusters. +In other words, although ScyllaCluster API exposes the machinery necessary for setting up multi-datacenter ScylaDB clusters, the ScyllaDB Operator only automates operations for a single datacenter.

        +

        Operations related to multiple datacenters may require manual intervention of a human operator. +Most notably, destroying one of the Kubernetes clusters or ScyllaDB datacenters is going to leave DN nodes behind in other datacenters, and their removal has to be carried out manually.

        +
        +

        The main mechanism used to set up a manual multi-datacenter ScyllaDB cluster is a field in ScyllaCluster’s specification - externalSeeds.

        +
        +

        External seeds

        +

        The externalSeeds field in ScyllaCluster’s specification enables control over external seeds that are propagated to ScyllaDB binary as --seed-provider-parameters seeds=<external-seeds>. +In this context, external should be understood as “external to the datacenter being specified by the API”. +The provided seeds are used by the nodes as initial points of contact, which allows them to discover the cluster ring topology when joining it.

        +

        Refer to Scylla Seed Nodes in ScyllaDB documentation for more information regarding the function of seed nodes in ScyllaDB. +For more details regarding the function and implementation of external seeds, refer to the original enhancement proposal.

        +
        +
        +

        Networking

        +

        Since this guide assumes interconnectivity over PodIPs of the Kubernetes clusters, you are going to configure the ScyllaDB cluster’s nodes to communicate over PodIPs. +This is enabled by a subset of exposeOptions specified in ScyllaCluster API, introduced in v1.11.

        +

        For this particular setup, define the ScyllaClusers as follows:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +spec:
        +  exposeOptions:
        +    nodeService:
        +      type: Headless
        +    broadcastOptions:
        +      clients:
        +        type: PodIP
        +      nodes:
        +        type: PodIP
        +
        +
        +

        However, other configuration options allow for the manual deployment of multi-datacenter ScyllaDB clusters in different network setups. For details, refer to Exposing ScyllaClusters in ScyllaDB Operator documentation.

        +
        +

        Deploy a multi-datacenter ScyllaDB Cluster

        +
        +
        +

        Using context

        +

        Let’s specify contexts for kubectl commands used throughout the guide. +To retrieve the context of your current cluster, run:

        +
        kubectl config current-context
        +
        +
        +

        Save the contexts of the two clusters, which you are going to deploy the datacenters in, as CONTEXT_DC1 and CONTEXT_DC2 environment variables correspondingly.

        +
        +
        +

        Deploy the first datacenter

        +

        First, run the below command to create a dedicated ‘scylla’ namespace:

        +
        kubectl --context="${CONTEXT_DC1}" create ns scylla
        +
        +
        +

        For this guide, let’s assume that your cluster is running in us-east-1 region and the nodes dedicated to running ScyllaDB nodes are running in zones us-east-1a, us-east-1b and us-east-1c correspondingly. If that is not the case, adjust the manifest accordingly.

        +
        +

        Caution

        +

        The .spec.name field of the ScyllaCluster objects represents the ScyllaDB cluster name and has to be consistent across all datacenters of this ScyllaDB cluster. +The names of the datacenters, specified in .spec.datacenter.name, have to be unique across the entire multi-datacenter cluster.

        +

        For more information see Create a ScyllaDB Cluster - Multi Data Centers (DC) in ScyllaDB documentation.

        +
        +

        Save the ScyllaCluster manifest in dc1.yaml:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +metadata:
        +  name: scylla-cluster
        +  namespace: scylla
        +spec:
        +  version: 5.2.7
        +  agentVersion: 3.1.2
        +  cpuset: true
        +  sysctls:
        +  - "fs.aio-max-nr=2097152"
        +  automaticOrphanedNodeCleanup: true
        +  exposeOptions:
        +    broadcastOptions:
        +      clients:
        +        type: PodIP
        +      nodes:
        +        type: PodIP
        +    nodeService:
        +      type: Headless
        +  datacenter:
        +    name: us-east-1
        +    racks:
        +    - name: a
        +      members: 1
        +      storage:
        +        storageClassName: scylladb-local-xfs
        +        capacity: 1800G
        +      agentResources:
        +        requests:
        +          cpu: 100m
        +          memory: 250M
        +        limits:
        +          cpu: 100m
        +          memory: 250M
        +      resources:
        +        requests:
        +          cpu: 7
        +          memory: 56G
        +        limits:
        +          cpu: 7
        +          memory: 56G
        +      placement:
        +        podAntiAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +          - topologyKey: kubernetes.io/hostname
        +            labelSelector:
        +              matchLabels:
        +                app.kubernetes.io/name: scylla
        +                scylla/cluster: scylla-cluster
        +        nodeAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +            nodeSelectorTerms:
        +            - matchExpressions:
        +              - key: topology.kubernetes.io/zone
        +                operator: In
        +                values:
        +                - us-east-1a
        +              - key: scylla.scylladb.com/node-type
        +                operator: In
        +                values:
        +                - scylla
        +        tolerations:
        +        - key: role
        +          operator: Equal
        +          value: scylla-clusters
        +          effect: NoSchedule
        +    - name: b
        +      members: 1
        +      storage:
        +        storageClassName: scylladb-local-xfs
        +        capacity: 1800G
        +      agentResources:
        +        requests:
        +          cpu: 100m
        +          memory: 250M
        +        limits:
        +          cpu: 100m
        +          memory: 250M
        +      resources:
        +        requests:
        +          cpu: 7
        +          memory: 56G
        +        limits:
        +          cpu: 7
        +          memory: 56G
        +      placement:
        +        podAntiAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +          - topologyKey: kubernetes.io/hostname
        +            labelSelector:
        +              matchLabels:
        +                app.kubernetes.io/name: scylla
        +                scylla/cluster: scylla-cluster
        +        nodeAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +            nodeSelectorTerms:
        +            - matchExpressions:
        +              - key: topology.kubernetes.io/zone
        +                operator: In
        +                values:
        +                - us-east-1b
        +              - key: scylla.scylladb.com/node-type
        +                operator: In
        +                values:
        +                - scylla
        +        tolerations:
        +        - key: role
        +          operator: Equal
        +          value: scylla-clusters
        +          effect: NoSchedule
        +    - name: c
        +      members: 1
        +      storage:
        +        storageClassName: scylladb-local-xfs
        +        capacity: 1800G
        +      agentResources:
        +        requests:
        +          cpu: 100m
        +          memory: 250M
        +        limits:
        +          cpu: 100m
        +          memory: 250M
        +      resources:
        +        requests:
        +          cpu: 7
        +          memory: 56G
        +        limits:
        +          cpu: 7
        +          memory: 56G
        +      placement:
        +        podAntiAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +          - topologyKey: kubernetes.io/hostname
        +            labelSelector:
        +              matchLabels:
        +                app.kubernetes.io/name: scylla
        +                scylla/cluster: scylla-cluster
        +        nodeAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +            nodeSelectorTerms:
        +            - matchExpressions:
        +              - key: topology.kubernetes.io/zone
        +                operator: In
        +                values:
        +                - us-east-1c
        +              - key: scylla.scylladb.com/node-type
        +                operator: In
        +                values:
        +                - scylla
        +        tolerations:
        +        - key: role
        +          operator: Equal
        +          value: scylla-clusters
        +          effect: NoSchedule
        +
        +
        +

        Apply the manifest:

        +
        kubectl --context="${CONTEXT_DC1}" apply --server-side -f=dc1.yaml
        +
        +
        +

        Wait for the cluster to be fully rolled out:

        +
        kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
        +
        +
        +
        scyllacluster.scylla.scylladb.com/scylla-cluster condition met
        +
        +
        +
        kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
        +
        +
        +
        scyllacluster.scylla.scylladb.com/scylla-cluster condition met
        +
        +
        +
        kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster
        +
        +
        +
        scyllacluster.scylla.scylladb.com/scylla-cluster condition met
        +
        +
        +

        You can now verify that all the nodes of your cluster are in UN state:

        +
        kubectl --context="${CONTEXT_DC1}" -n=scylla exec -it pod/scylla-cluster-us-east-1-a-0 -c=scylla -- nodetool status
        +
        +
        +

        The expected output should look similar to the below:

        +
        Datacenter: us-east-1
        +=====================
        +Status=Up/Down
        +|/ State=Normal/Leaving/Joining/Moving
        +--  Address      Load       Tokens       Owns    Host ID                               Rack
        +UN  10.0.70.195  290 KB     256          ?       494277b9-121c-4af9-bd63-3d0a7b9305f7  c
        +UN  10.0.59.24   559 KB     256          ?       a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37  b
        +UN  10.0.19.237  107 KB     256          ?       64b6292a-327f-4128-852a-6004039f402e  a
        +
        +
        +
        +
        Retrieve PodIPs of ScyllaDB nodes for use as external seeds
        +
        +

        Warning

        +

        Due to the ephemeral nature of PodIPs, it is ill-advised to use them as seeds in production environments. +This is because there is a high likelihood that the Pods of your ScyllaDB clusters will change their IPs during the cluster’s lifecycle, and so the provided seeds will no longer point to the ScyllaDB nodes. +It is undesired, as the seeds provided on node’s startup may serve as fallback contact points when all of the node’s peers are unreachable. +In production environments, it is recommended that you use domain names or non-ephemeral IP addresses as external seeds. +PodIPs are being used in this example for the sheer simplicity of this setup.

        +
        +

        Use the below commands and their expected outputs as a reference for retrieving the PodIPs used by the cluster for inter-node communication.

        +
        kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-a-0 --template='{{ .status.podIP }}'
        +
        +
        +
        10.0.19.237
        +
        +
        +
        kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-b-0 --template='{{ .status.podIP }}'
        +
        +
        +
        10.0.59.24
        +
        +
        +
        kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-c-0 --template='{{ .status.podIP }}'
        +
        +
        +
        10.0.70.195
        +
        +
        +

        You are going to utilize the retrieved addresses as seeds for the other datacenter.

        +
        +
        +
        +

        Deploy the second datacenter

        +

        To deploy the second datacenter, you will follow similar steps.

        +

        First, create a dedicated ‘scylla’ namespace:

        +
        kubectl --context="${CONTEXT_DC2}" create ns scylla
        +
        +
        +

        Replace the values in .spec.externalSeeds of the below manifest with the Pod IP addresses that you retrieved earlier. +The provided values are going to serve as initial contact points for the joining nodes of the second datacenter.

        +

        For this guide, let’s assume that the second cluster is running in us-east-2 region and the nodes dedicated for running ScyllaDB nodes are running in zones us-east-2a, us-east-2b and us-east-2c correspondingly. If that is not the case, adjust the manifest accordingly. +Having configured it, save the manifest as dc2.yaml:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +metadata:
        +  name: scylla-cluster
        +  namespace: scylla
        +spec:
        +  version: 5.2.7
        +  agentVersion: 3.1.2
        +  cpuset: true
        +  sysctls:
        +  - "fs.aio-max-nr=2097152"
        +  automaticOrphanedNodeCleanup: true
        +  exposeOptions:
        +    broadcastOptions:
        +      clients:
        +        type: PodIP
        +      nodes:
        +        type: PodIP
        +    nodeService:
        +      type: Headless
        +  externalSeeds:
        +  - 10.0.19.237
        +  - 10.0.59.24
        +  - 10.0.70.195
        +  datacenter:
        +    name: us-east-2
        +    racks:
        +    - name: a
        +      members: 1
        +      storage:
        +        storageClassName: scylladb-local-xfs
        +        capacity: 1800G
        +      agentResources:
        +        requests:
        +          cpu: 100m
        +          memory: 250M
        +        limits:
        +          cpu: 100m
        +          memory: 250M
        +      resources:
        +        requests:
        +          cpu: 7
        +          memory: 56G
        +        limits:
        +          cpu: 7
        +          memory: 56G
        +      placement:
        +        podAntiAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +          - topologyKey: kubernetes.io/hostname
        +            labelSelector:
        +              matchLabels:
        +                app.kubernetes.io/name: scylla
        +                scylla/cluster: scylla-cluster
        +        nodeAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +            nodeSelectorTerms:
        +            - matchExpressions:
        +              - key: topology.kubernetes.io/zone
        +                operator: In
        +                values:
        +                - us-east-2a
        +              - key: scylla.scylladb.com/node-type
        +                operator: In
        +                values:
        +                - scylla
        +        tolerations:
        +        - key: role
        +          operator: Equal
        +          value: scylla-clusters
        +          effect: NoSchedule
        +    - name: b
        +      members: 1
        +      storage:
        +        storageClassName: scylladb-local-xfs
        +        capacity: 1800G
        +      agentResources:
        +        requests:
        +          cpu: 100m
        +          memory: 250M
        +        limits:
        +          cpu: 100m
        +          memory: 250M
        +      resources:
        +        requests:
        +          cpu: 7
        +          memory: 56G
        +        limits:
        +          cpu: 7
        +          memory: 56G
        +      placement:
        +        podAntiAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +          - topologyKey: kubernetes.io/hostname
        +            labelSelector:
        +              matchLabels:
        +                app.kubernetes.io/name: scylla
        +                scylla/cluster: scylla-cluster
        +        nodeAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +            nodeSelectorTerms:
        +            - matchExpressions:
        +              - key: topology.kubernetes.io/zone
        +                operator: In
        +                values:
        +                - us-east-2b
        +              - key: scylla.scylladb.com/node-type
        +                operator: In
        +                values:
        +                - scylla
        +        tolerations:
        +        - key: role
        +          operator: Equal
        +          value: scylla-clusters
        +          effect: NoSchedule
        +    - name: c
        +      members: 1
        +      storage:
        +        storageClassName: scylladb-local-xfs
        +        capacity: 1800G
        +      agentResources:
        +        requests:
        +          cpu: 100m
        +          memory: 250M
        +        limits:
        +          cpu: 100m
        +          memory: 250M
        +      resources:
        +        requests:
        +          cpu: 7
        +          memory: 56G
        +        limits:
        +          cpu: 7
        +          memory: 56G
        +      placement:
        +        podAntiAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +          - topologyKey: kubernetes.io/hostname
        +            labelSelector:
        +              matchLabels:
        +                app.kubernetes.io/name: scylla
        +                scylla/cluster: scylla-cluster
        +        nodeAffinity:
        +          requiredDuringSchedulingIgnoredDuringExecution:
        +            nodeSelectorTerms:
        +            - matchExpressions:
        +              - key: topology.kubernetes.io/zone
        +                operator: In
        +                values:
        +                - us-east-2c
        +              - key: scylla.scylladb.com/node-type
        +                operator: In
        +                values:
        +                - scylla
        +        tolerations:
        +        - key: role
        +          operator: Equal
        +          value: scylla-clusters
        +          effect: NoSchedule
        +
        +
        +

        To apply the manifest, run:

        +
        kubectl --context="${CONTEXT_DC2}" -n=scylla apply --server-side -f=dc2.yaml
        +
        +
        +

        Wait for the second datacenter to roll out:

        +
        kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
        +
        +
        +
        scyllacluster.scylla.scylladb.com/scylla-cluster condition met
        +
        +
        +
        kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
        +
        +
        +
        scyllacluster.scylla.scylladb.com/scylla-cluster condition met
        +
        +
        +
        kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster
        +
        +
        +
        scyllacluster.scylla.scylladb.com/scylla-cluster condition met
        +
        +
        +

        You can verify that the nodes have joined the existing cluster and that you are now running a multi-datacenter ScyllaDB cluster by running nodetool status with the below command:

        +
        kubectl --context="${CONTEXT_DC2}" -n=scylla exec -it pod/scylla-cluster-us-east-2-a-0 -c=scylla -- nodetool status
        +
        +
        +
        Datacenter: us-east-1
        +=====================
        +Status=Up/Down
        +|/ State=Normal/Leaving/Joining/Moving
        +--  Address        Load       Tokens       Owns    Host ID                               Rack
        +UN  10.0.70.195    705 KB     256          ?       494277b9-121c-4af9-bd63-3d0a7b9305f7  c
        +UN  10.0.59.24     764 KB     256          ?       a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37  b
        +UN  10.0.19.237    634 KB     256          ?       64b6292a-327f-4128-852a-6004039f402e  a
        +Datacenter: us-east-2
        +=====================
        +Status=Up/Down
        +|/ State=Normal/Leaving/Joining/Moving
        +--  Address        Load       Tokens       Owns    Host ID                               Rack
        +UN  172.16.39.209  336 KB     256          ?       7c30ea55-7a4f-4d93-86f7-c881772ebe62  b
        +UN  172.16.25.18   759 KB     256          ?       665dde7e-e420-4db3-8c54-ca71efd39b2e  a
        +UN  172.16.87.27   503 KB     256          ?       c19c89cb-e24c-4062-9df4-2aa90ab29a99  c
        +
        +
        +
        +
        +
        +
        +

        Scylla Manager

        +

        To integrate a multi-datacenter ScyllaDB cluster with Scylla Manager, you must deploy the Scylla Manager in only one datacenter.

        +

        In this example, let’s choose the Kubernetes cluster deployed in the first datacenter to host it. +To deploy Scylla Manager, follow the steps described in Deploying Scylla Manager on a Kubernetes Cluster +in ScyllaDB Operator documentation.

        +

        In order to define the Scylla Manager tasks, add them to the ScyllaCluster object deployed in the same Kubernetes cluster +in which your Scylla Manager is running.

        +

        Every datacenter (represented by ScyllaCluster CR) is, by default, provisioned with a new, random Scylla Manager Agent auth token. +To use Scylla Manager with multiple datacenter (represented by ScyllaClusters), you have to make sure they all use the same token.

        +

        Extract it from the first datacenter with the below command:

        +
        kubectl --context="${CONTEXT_DC1}" -n=scylla get secrets/scylla-cluster-auth-token --template='{{ index .data "auth-token.yaml" }}' | base64 -d
        +
        +
        +
        auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf
        +
        +
        +

        Save the output, replace the token with your own, and patch the secret in the second datacenter with the below command:

        +
        kubectl --context="${CONTEXT_DC2}" -n=scylla patch secret/scylla-cluster-auth-token--type='json' -p='[{"op": "add", "path": "/stringData", "value": {"auth-token.yaml": "auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf"}}]'
        +
        +
        +

        Execute a rolling restart of the nodes in DC2 to make sure they pick up the new token:

        +
        kubectl --context="${CONTEXT_DC2}" -n=scylla patch scyllacluster/scylla-cluster --type='merge' -p='{"spec": {"forceRedeploymentReason": "sync scylla-manager-agent token ('"$( date )"')"}}'
        +
        +
        +
        +
        +

        ScyllaDBMonitoring

        +

        To monitor your cluster, deploy ScyllaDBMonitoring in every datacenter independently. +To deploy ScyllaDB Monitoring, follow the steps described in Deploy managed monitoring in ScyllaDB Operator documentation.

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/nodeoperations/automatic-cleanup.html b/stable/nodeoperations/automatic-cleanup.html new file mode 100644 index 00000000000..4927fce6a83 --- /dev/null +++ b/stable/nodeoperations/automatic-cleanup.html @@ -0,0 +1,577 @@ + + + + + + + + + + + + + Automatic cleanup and replacement in case when k8s node is lost | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Automatic cleanup and replacement in case when k8s node is lost

        +

        In case when your k8s cluster loses one of the nodes due to incident or explicit removal, Scylla Pods may become unschedulable due to PVC node affinity.

        +

        When automaticOrphanedNodeCleanup flag is enabled in your ScyllaCluster, Scylla Operator will perform automatic +node replacement of a Pod which lost his bound resources.

        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/nodeoperations/index.html b/stable/nodeoperations/index.html new file mode 100644 index 00000000000..4e741fc1d58 --- /dev/null +++ b/stable/nodeoperations/index.html @@ -0,0 +1,577 @@ + + + + + + + + + + + + + Node operations using Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Node operations using Scylla Operator

        +
        +
        +

        Choose a topic:

        + +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/nodeoperations/maintenance-mode.html b/stable/nodeoperations/maintenance-mode.html new file mode 100644 index 00000000000..534467acc89 --- /dev/null +++ b/stable/nodeoperations/maintenance-mode.html @@ -0,0 +1,586 @@ + + + + + + + + + + + + + Maintenance mode | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Maintenance mode

        +

        When maintenance mode is enabled, readiness probe of Scylla Pod will always return failure and liveness probe will always succeed. This causes that Pod under maintenance +is being removed from K8s Load Balancer and DNS registry but Pod itself stays alive.

        +

        This allows the Scylla Operator to interact with Scylla and Scylla dependencies inside the Pod. +For example user may turn off Scylla process, do something with the filesystem and bring the process back again.

        +

        To enable maintenance mode add scylla/node-maintenance label to service in front of Scylla Pod.

        +
        kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance=""
        +
        +
        +

        To disable, simply remove this label from service.

        +
        kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance-
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/nodeoperations/replace-node.html b/stable/nodeoperations/replace-node.html new file mode 100644 index 00000000000..45a22bad993 --- /dev/null +++ b/stable/nodeoperations/replace-node.html @@ -0,0 +1,660 @@ + + + + + + + + + + + + + Replacing a Scylla node | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Replacing a Scylla node

        +
        +

        Replacing a dead node

        +

        In the case of a host failure, it may not be possible to bring back the node to life.

        +

        Replace dead node operation will cause the other nodes in the cluster to stream data to the node that was replaced. +This operation can take some time (depending on the data size and network bandwidth).

        +

        This procedure is for replacing one dead node. To replace more than one dead node, run the full procedure to completion one node at a time

        +

        Procedure

        +
          +
        1. Verify the status of the node using nodetool status command, the node with status DN is down and need to be replaced

          +
          kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
          +Datacenter: us-east-1
          +=====================
          +Status=Up/Down
          +|/ State=Normal/Leaving/Joining/Moving
          +--  Address        Load       Tokens       Owns    Host ID                               Rack
          +UN  10.43.125.110  74.63 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
          +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
          +DN  10.43.43.51    74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
          +
          +
          +
        2. +
        3. Identify service which is bound to down node by checking IP address

          +
          kubectl -n scylla get svc
          +NAME                                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                           AGE
          +simple-cluster-client                   ClusterIP   None            <none>        9180/TCP                                                          3h12m
          +simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.231.189   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h12m
          +simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.125.110   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h11m
          +simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.43.51     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h5m
          +
          +
          +
        4. +
        5. Drain node which we would like to replace using. This command may delete your data from local disks attached to given node!

          +
          kubectl drain gke-scylla-demo-default-pool-b4b390a1-6j12 --ignore-daemonsets --delete-local-data
          +
          +
          +

          Pod which will be replaced should enter the Pending state

          +
          kubectl -n scylla get pods
          +NAME                                    READY   STATUS    RESTARTS   AGE
          +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h21m
          +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h19m
          +simple-cluster-us-east-1-us-east-1a-2   0/2     Pending   0          8m14s
          +
          +
          +
        6. +
        7. To being node replacing, add scylla/replace="" label to service bound to pod we are replacing.

          +
          kubectl -n scylla label svc simple-cluster-us-east-1-us-east-1a-2 scylla/replace=""
          +
          +
          +

          Your failed Pod should be recreated on available k8s node

          +
          kubectl -n scylla get pods
          +NAME                                    READY   STATUS    RESTARTS   AGE
          +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h27m
          +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h25m
          +simple-cluster-us-east-1-us-east-1a-2   1/2     Running   0          9s
          +
          +
          +

          Because other nodes in cluster must stream data to new node this operation might take some time depending on how much data your cluster stores. +After bootstraping is over, your new Pod should be ready to go. +Old one shouldn’t be no longer visible in nodetool status

          +
          kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
          +Datacenter: us-east-1
          +=====================
          +Status=Up/Down
          +|/ State=Normal/Leaving/Joining/Moving
          +--  Address        Load       Tokens       Owns    Host ID                               Rack
          +UN  10.43.125.110  74.62 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
          +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
          +UN  10.43.191.172  74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
          +
          +
          +
        8. +
        9. Run the repair on the cluster to make sure that the data is synced with the other nodes in the cluster. +You can use Scylla Manager to run the repair.

        10. +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/nodeoperations/restore.html b/stable/nodeoperations/restore.html new file mode 100644 index 00000000000..aecd1778988 --- /dev/null +++ b/stable/nodeoperations/restore.html @@ -0,0 +1,777 @@ + + + + + + + + + + + + + Restore from backup | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Restore from backup

        +

        This procedure will describe how to restore from backup taken using Scylla Manager to a fresh empty cluster of any size.

        +
        +

        Caution

        +

        Due to a bug in Scylla Manager not supporting ScyllaClusters having both non-TLS and TLS CQL ports open, you have to disable the TLS certificate management +in Scylla Operator. +This step will no longer be required, when the bug is fixed.

        +

        To disable TLS certificate management in Scylla Operator add --feature-gates="AutomaticTLSCertificates=false" flag to Scylla Operator deployment.

        +
        kubectl -n scylla-operator patch deployment/scylla-operator --type=json -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--feature-gates=AutomaticTLSCertificates=false"}]'
        +
        +
        +
        +

        In the following example, the ScyllaCluster, which was used to take the backup, is called source. Backup will be restored into the ScyllaCluster named target.

        +
        + +
        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +metadata:
        +  name: source
        +  namespace: scylla
        +spec:
        +  agentVersion: 3.2.5
        +  version: 5.4.1
        +  developerMode: true
        +  backups:
        +  - name: foo
        +    location:
        +    - s3:source-backup
        +    keyspace:
        +    - '*'
        +  datacenter:
        +    name: us-east-1
        +    racks:
        +    - name: us-east-1a
        +      members: 1
        +      storage:
        +        capacity: 1Gi
        +      resources:
        +        limits:
        +          cpu: 1
        +          memory: 1Gi
        +
        +
        +
        + +
        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +metadata:
        +  name: target
        +  namespace: scylla
        +spec:
        +  agentVersion: 3.2.5
        +  version: 5.4.1
        +  developerMode: true
        +  datacenter:
        +    name: us-east-1
        +    racks:
        +    - name: us-east-1a
        +      members: 1
        +      storage:
        +        capacity: 1Gi
        +      resources:
        +        limits:
        +          cpu: 1
        +          memory: 1Gi
        +
        +
        +
        +
        +

        Make sure your target cluster is already registered in Scylla Manager. To get a list of all registered clusters, execute the following command:

        +
        $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool cluster list
        ++--------------------------------------+---------------------------------------+---------+-----------------+
        +| ID                                   | Name                                  | Port    | CQL credentials |
        ++--------------------------------------+---------------------------------------+---------+-----------------+
        +| af1dd5cd-0406-4974-949f-dc9842980080 | scylla/target                        | default | set             |
        +| ebd82268-efb7-407e-a540-3619ae053778 | scylla/source                        | default | set             |
        ++--------------------------------------+---------------------------------------+---------+-----------------+
        +
        +
        +

        Identify the tag of a snapshot which you want to restore. To get a list of all available snapshots, execute following command:

        +
        kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c <CLUSTER_ID> --all-clusters -L <BACKUP_LOCATION>
        +
        +
        +

        Where:

        +
          +
        • CLUSTER_ID - the name or ID of a registered cluster with access to BACKUP_LOCATION.

        • +
        • BACKUP_LOCATION - the location in which the backup is stored.

        • +
        +

        In this example, BACKUP_LOCATION is s3:source-backup. Use the name of cluster which has access to the backup location for CLUSTER_ID. +In this example, it’s scylla/target.

        +
        $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c scylla/target --all-clusters -L s3:source-backup
        +backup/ff36d7e0-af2e-458c-afe6-868e0f3396b2
        +Snapshots:
        +  - sm_20240105115931UTC (409MiB, 1 nodes)
        +Keyspaces:
        +  - system_schema (15 tables)
        +  - users (9 tables)
        +
        +
        +

        In the below commands, we are restoring the sm_20240105115931UTC snapshot. Replace it with a tag of a snapshot that you want to restore. +Restoring consist of two steps. First, you’ll restore the schema, and then the data. +To restore schema, create a restore task manually on target ScyllaCluster by executing following command:

        +
        kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager --  sctool restore -c <CLUSTER_ID> -L <BACKUP_LOCATION> -T <SNAPSHOT_TAG> --restore-schema
        +
        +
        +

        Where:

        +
          +
        • CLUSTER_ID - a name or ID of a cluster you want to restore into.

        • +
        • BACKUP_LOCATION - the location in which the backup is stored.

        • +
        • SNAPSHOT_TAG - a tag of a snapshot that you want to restore.

        • +
        +

        When the task is created, the command will output the ID of a restore task.

        +
        $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-schema
        +restore/57228c52-7cf6-4271-8c8d-d446ff160747
        +
        +
        +

        Use the following command to check progress of the restore task:

        +
        $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/57228c52-7cf6-4271-8c8d-d446ff160747
        +Restore progress
        +Run:            0dd20cdf-abc4-11ee-951c-6e7993cf42ed
        +Status:         DONE - restart required (see restore docs)
        +Start time:     05 Jan 24 12:15:02 UTC
        +End time:       05 Jan 24 12:15:09 UTC
        +Duration:       6s
        +Progress:       100% | 100%
        +Snapshot Tag:   sm_20240105115931UTC
        +
        ++---------------+-------------+----------+----------+------------+--------+
        +| Keyspace      |    Progress |     Size |  Success | Downloaded | Failed |
        ++---------------+-------------+----------+----------+------------+--------+
        +| system_schema | 100% | 100% | 214.150k | 214.150k |   214.150k |      0 |
        ++---------------+-------------+----------+----------+------------+--------+
        +
        +
        +

        As suggested in the progress output, you will need to execute a rolling restart of the ScyllaCluster.

        +
        kubectl patch scyllacluster target --type merge -p '{"spec": {"forceRedeploymentReason": "schema restored"}}'
        +
        +
        +

        Use the following commands to wait until restart is finished:

        +
        $ kubectl wait --for='condition=Progressing=False' -n scylla scyllaclusters.scylla.scylladb.com/target
        +scyllacluster.scylla.scylladb.com/target condition met
        +
        +$ kubectl wait --for='condition=Degraded=False' -n scylla scyllaclusters.scylla.scylladb.com/target
        +scyllacluster.scylla.scylladb.com/target condition met
        +
        +$ kubectl wait --for='condition=Available=True' -n scylla scyllaclusters.scylla.scylladb.com/target
        +scyllacluster.scylla.scylladb.com/target condition met
        +
        +
        +

        To restore the tables content, create a restore task manually on target ScyllaCluster by executing the following command:

        +
        kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c <CLUSTER_ID> -L <BACKUP_LOCATION> -T <SNAPSHOT_TAG> --restore-tables
        +
        +
        +

        Where:

        +
          +
        • CLUSTER_ID - a name or ID of a cluster you want to restore into.

        • +
        • BACKUP_LOCATION - the location in which the backup is stored.

        • +
        • SNAPSHOT_TAG - a tag of a snapshot that you want to restore.

        • +
        +

        When the task is created, the command will output the ID of a restore task.

        +
        $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-tables
        +restore/63642069-bed5-4def-ba0f-68c49e47ace1
        +
        +
        +

        Use the following command to check progress of the restore task:

        +
        $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/63642069-bed5-4def-ba0f-68c49e47ace1
        +Restore progress
        +Run:            ab015cef-abc8-11ee-9521-6e7993cf42ed
        +Status:         DONE
        +Start time:     05 Jan 24 12:48:04 UTC
        +End time:       05 Jan 24 12:48:15 UTC
        +Duration:       11s
        +Progress:       100% | 100%
        +Snapshot Tag:   sm_20240105115931UTC
        +
        ++-------------+-------------+--------+---------+------------+--------+
        +| Keyspace    |    Progress |   Size | Success | Downloaded | Failed |
        ++-------------+-------------+--------+---------+------------+--------+
        +| users       | 100% | 100% | 409MiB |  409MiB |     409MiB |      0 |
        ++-------------+-------------+--------+---------+------------+--------+
        +
        +Post-restore repair progress
        +Run:            ab015cef-abc8-11ee-9521-6e7993cf42ed
        +Status:         DONE
        +Start time:     05 Jan 24 12:48:04 UTC
        +End time:       05 Jan 24 12:48:15 UTC
        +Duration:       11s
        +Progress:       100%
        +Intensity:      1
        +Parallel:       0
        +Datacenters:
        +  - us-east-1
        +
        ++-------------+--------------+----------+----------+
        +| Keyspace    |        Table | Progress | Duration |
        ++-------------+--------------+----------+----------+
        +| users       | users        | 100%     | 0s       |
        ++-------------+--------------+----------+----------+
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/nodeoperations/scylla-upgrade.html b/stable/nodeoperations/scylla-upgrade.html new file mode 100644 index 00000000000..fa41ab2c166 --- /dev/null +++ b/stable/nodeoperations/scylla-upgrade.html @@ -0,0 +1,659 @@ + + + + + + + + + + + + + Upgrading version of Scylla | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Upgrading version of Scylla

        +

        To upgrade Scylla version using Operator user have to modify existing ScyllaCluster definition.

        +

        In this example cluster will be upgraded to version 4.4.5.

        +
        kubectl -n scylla patch ScyllaCluster simple-cluster  -p '{"spec":{"version": "4.4.5"}}' --type=merge
        +
        +
        +

        Operator supports two types of version upgrades:

        +
          +
        1. Patch upgrade

        2. +
        3. Generic upgrade

        4. +
        +

        Patch upgrade

        +

        Patch upgrade is executed when only patch version change is detected according to semantic versioning format. +Procedure simply rolls out a restart of whole cluster and upgrades Scylla container image for each node one by one.

        +

        Example: 4.0.0 -> 4.0.1

        +

        Generic upgrade

        +

        Generic upgrades are executed for the non patch version changes.

        +

        Example: 4.0.0 -> 2020.1.0 or 4.0.0 -> 4.1.0 or even 4.0.0 -> nightly

        +

        User can observe current state of upgrade in ScyllaCluster status.

        +
        kubectl -n scylla describe ScyllaCluster simple-cluster
        +[...]
        +Status:
        +  Racks:
        +    us-east-1a:
        +      Members:        3
        +      Ready Members:  3
        +      Version:        4.1.9
        +  Upgrade:
        +    Current Node:         simple-cluster-us-east-1-us-east-1a-2
        +    Current Rack:         us-east-1a
        +    Data Snapshot Tag:    so_data_20201228135002UTC
        +    From Version:         4.1.9
        +    State:                validate_upgrade
        +    System Snapshot Tag:  so_system_20201228135002UTC
        +    To Version:           4.2.2
        +
        +
        +

        Each upgrade begins with taking a snapshot of system and system_schema keyspaces on all nodes in parallel. +Name of this snapshot tag is saved in upgrade status under System Snapshot Tag.

        +

        Before nodes in rack are upgraded, underlying StatefulSet is changed to use OnDelete UpgradeStrategy. +This allows Operator have a full control over when Pod image is changed.

        +

        When a node is being upgraded, maintenance mode is enabled, then the node is drained and snapshot of all data keyspaces is taken. +Snapshot tag is saved under Data Snapshot Tag and is the same for all nodes during the procedure. +Once everything is set up, maintenance mode is disabled and Scylla Pod is deleted. Underlying StatefulSet will bring up a new +Pod with upgraded version. +Once Pod will become ready, data snapshot from this particular node is removed, and Operator moves to next node.

        +

        Once every rack is upgraded, system snapshot is removed from all nodes in parallel and previous StatefulSet UpgradeStrategy is restored. +At this point, all your nodes should be already in desired version.

        +

        Current state of upgrade can be traced using Current Node, Current Rack and State status fields.

        +
          +
        • Current Node shows which node is being upgraded.

        • +
        • Current Rack displays which rack is being upgraded.

        • +
        • State contain information at which stage upgrade is.

        • +
        +

        State can have following values:

        +
          +
        • begin_upgrade - upgrade is starting

        • +
        • check_schema_agreement - Operator waits until all nodes reach schema agreement. It waits for it for 1 minute, prints an error log message and check is retried.

        • +
        • create_system_backup - system keyspaces snapshot is being taken

        • +
        • find_next_rack - Operator finds out which rack must be upgraded next, decision is saved in Current Rack

        • +
        • upgrade_image_in_pod_spec - Image and UpgradeStrategy is upgraded in underlying StatefulSet

        • +
        • find_next_node - Operator finds out which node must be upgraded next, decision is saved in Current Node

        • +
        • enable_maintenance_mode - maintenance mode is being enabled

        • +
        • drain_node - node is being drained

        • +
        • backup_data - snapshot of data keyspaces is being taken

        • +
        • disable_maintenance_mode - maintenance mode is being disabled

        • +
        • delete_pod - Scylla Pod is being deleted

        • +
        • validate_upgrade - Operator validates if new pod enters Ready state and if Scylla version is upgraded

        • +
        • clear_data_backup - snapshot of data keyspaces is being removed

        • +
        • clear_system_backup - snapshot of system keyspaces is being removed

        • +
        • restore_upgrade_strategy - restore UpgradeStrategy in underlying StatefulSet

        • +
        • finish_upgrade - upgrade cleanup

        • +
        +

        Recovering from upgrade failure

        +

        Upgrade may get stuck on validate_upgrade stage. This happens when Scylla Pod refuses to properly boot up.

        +

        To continue with upgrade, first turn off operator by scaling Operator replicas to zero:

        +
        kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=0
        +
        +
        +

        Then user have to manually resolve issue with Scylla by checking what is the root cause of a failure in Scylla container logs. +If needed data and system keyspaces SSTable snapshots are available on the node. You can check ScyllaCluster status for their names.

        +

        Once issue is resolved and Scylla Pod is up and running (Pod is in Ready state), scale Operator back to two replicas:

        +
        kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=2
        +
        +
        +

        Operator should continue upgrade process from where it left off.

        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/objects.inv b/stable/objects.inv new file mode 100644 index 00000000000..02d81b59158 --- /dev/null +++ b/stable/objects.inv @@ -0,0 +1,7 @@ +# Sphinx inventory version 2 +# Project: Scylla Operator +# Version: +# The remainder of this file is compressed using zlib. +xڝVn0+j[[bma wX\__)Nы-fpll,;llWw1jO3=rN4J#؛Z&FJ3QYԂ%}HwƂF;yۂ`Jޢ'[Y+I[xD=4p9ԗ=/0%t]kASfYJjzV X$D蚛 ) Q,`  7H~+D}P;-d\Lhw$7Ds }[AA4i?wUA}k6O90?hz x>pOaR]nT{/ B_OW IՃ8@M "{}>pQB$2Q32vI,SAf2{=_3 KH +jPs|&t W[~H("䢾e]E5h%֯?7M ֹ/9IW| Y此^r3_Uj':.fhG;bG@ +VڒP)_&[i M6لeJ?폌G7KЉ ;fk['M@pBN2gs9m6ktU~ ^D) $ar[fP*ܥE$5] Qq1ns%L/Q \ No newline at end of file diff --git a/stable/performance.html b/stable/performance.html new file mode 100644 index 00000000000..3322b31accb --- /dev/null +++ b/stable/performance.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Performance tuning | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Performance tuning

        +

        Scylla Operator 1.6 introduces a new experimental feature allowing users to optimize Kubernetes nodes.

        +
        +

        Node tuning

        +

        Starting from Operator 1.6, a new CRD called NodeConfig is available, allowing users to target Nodes which should be tuned. +When a Node is supposed to be optimized, the Scylla Operator creates a DaemonSet covering these Nodes. +Nodes matching the provided placement conditions will be subject to tuning.

        +

        Below example NodeConfig tunes nodes having scylla.scylladb.com/node-type=scylla label:

        +
        apiVersion: scylla.scylladb.com/v1alpha1
        +kind: NodeConfig
        +metadata:
        + name: cluster
        +spec:
        + placement:
        +   nodeSelector:
        +     scylla.scylladb.com/node-type: scylla
        +
        +
        +

        For more details about new CRD use:

        +
        kubectl explain nodeconfigs.scylla.scylladb.com/v1alpha1
        +
        +
        +

        For all optimizations we use a Python script available in the Scylla image called perftune. +Perftune executes the performance optmizations like tuning the kernel, network, disk devices, spreading IRQs across CPUs and more.

        +

        Tuning consists of two separate optimizations: common node tuning, and tuning based on Scylla Pods and their resource assignment. +Node tuning is executed immediately. Pod tuning is executed when Scylla Pod lands on the same Node.

        +

        Scylla works most efficently when it’s pinned to CPU and not interrupted. +One of the most common causes of context-switching are network interrupts. Packets coming to a node need to be processed, +and this requires CPU shares.

        +

        On K8s we always have at least a couple of processes running on the node: kubelet, kubernetes provider applications, daemons etc. +These processes require CPU shares, so we cannot dedicate entire node processing power to Scylla, we need to leave space for others.
        +We take advantage of it, and we pin IRQs to CPUs not used by any Scylla Pods exclusively.

        +

        Tuning resources are created in a special namespace called scylla-operator-node-tuning.

        +

        The tuning is applied only to pods with Guaranteed QoS class. Please double check your ScyllaCluster resource specification +to see if it meets all conditions.

        +
        +
        +

        Kubernetes tuning

        +

        By default, the kubelet uses the CFS quota to enforce pod CPU limits.
        +When the node runs many CPU-bound pods, the workload can move around different CPU cores depending on whether the pod +is throttled and which CPU cores are available. +However, kubelet may be configured to assign CPUs exclusively, by setting the CPU manager policy to static.

        +

        Setting up kubelet configuration is provider specific. Please check the docs for your distribution or talk to your +provider.

        +

        Only pods within the Guaranteed QoS class) can take advantage of this option. +When such pod lands on a Node, kubelet will pin them to specific CPUs, and those won’t be part of the shared pool.

        +

        In our case there are two requirements each ScyllaCluster must fulfill to receive a Guaranteed QoS class:

        +
          +
        • resource request and limits must be equal or only limits have to be provided

        • +
        • agentResources must be provided and their requests and limits must be equal, or only limits have to be provided

        • +
        +

        An example of such a ScyllaCluster that receives a Guaranteed QoS class is below:

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +metadata:
        +  name: guaranteed-cluster
        +  namespace: scylla
        +spec:
        +  version: 4.5.1
        +  agentVersion: 2.5.2
        +  datacenter:
        +    name: us-east-1
        +    racks:
        +    - name: us-east-1a
        +      members: 3
        +      storage:
        +        capacity: 500Gi
        +      agentResources:
        +        requests:
        +          cpu: 1
        +          memory: 1G
        +        limits:
        +          cpu: 1
        +          memory: 1G
        +      resources:
        +        requests:
        +          cpu: 4
        +          memory: 16G
        +        limits:
        +          cpu: 4
        +          memory: 16G
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/releases.html b/stable/releases.html new file mode 100644 index 00000000000..0bca2a74300 --- /dev/null +++ b/stable/releases.html @@ -0,0 +1,816 @@ + + + + + + + + + + + + + Releases | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Releases

        +
        +

        Schedule

        +

        We are aiming to ship a new release approximately every 6 weeks. The following release schedule is only advisory, there are no commitments made to hitting these dates.

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

        Release

        Code freeze

        General availability

        1.11

        2023-10-02

        2023-10-16

        +
        +
        +

        Supported releases

        +

        We support the latest 2 releases of the operator to give everyone time to upgrade.

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

        Release

        General availability

        Support ends

        1.10

        2023-08-25

        Release of 1.12

        1.9

        2023-07-04

        Release of 1.11

        1.8

        2023-01-25

        2023-08-25

        1.7

        2022-01-27

        2023-07-04

        1.6

        2021-12-03

        2023-01-25

        1.5

        2021-09-16

        2022-01-27

        1.4

        2021-08-10

        2021-12-03

        1.3

        2021-06-17

        2021-09-16

        1.2

        2021-05-06

        2021-08-10

        1.1

        2021-03-22

        2021-06-17

        1.0

        2021-01-21

        2021-05-06

        +
        +

        Backport policy

        +

        Usually, only important bug fixes are eligible for being backported. +This may depend on the situation and assessment of the maintainers.

        +
        +
        +
        +

        CI/CD

        +

        We use GitHub actions for our CI/CD. Every merge to a supported branch, or a creation of a tag will automatically trigger a job to build, test and publish the container image and other artifacts like helm charts. Before we publish any image, it must pass the e2e suite.

        +
        +

        Automated promotions

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

        Git reference

        Type

        Container image

        master

        branch

        docker.io/scylladb/scylla-operator:latest

        vX.Y

        branch

        docker.io/scylladb/scylla-operator:X.Y

        vX.Y.Z

        tag

        docker.io/scylladb/scylla-operator:X.Y.Z

        vX.Y.Z-alpha.N

        tag

        docker.io/scylladb/scylla-operator:X.Y.Z-alpha.N

        vX.Y.Z-beta.N

        tag

        docker.io/scylladb/scylla-operator:X.Y.Z-beta.N

        vX.Y.Z-rc.N

        tag

        docker.io/scylladb/scylla-operator:X.Y.Z-rc.N

        +
        +
        +

        Generally available

        +

        GA images aren’t build from scratch but rather promoted from an existing release candidates. When we decide a release candidate has the acceptable quality and QA sings it off, the release candidate is promoted to become the GA release. This makes sure the image has exactly the same content and SHA as the tested release candidate.

        +
        +
        +
        +

        Support matrix

        +

        Support matrix table shows the version requirements for a particular scylla-operator version. Be sure to match these requirements, otherwise some functionality will not work.

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

        v1.10

        v1.9

        v1.8

        v1.7

        v1.6

        v1.5

        v1.4

        v1.3

        v1.2

        v1.1

        v1.0

        Kubernetes

        >=1.21

        >=1.21

        >=1.21

        >=1.20 && <1.25

        >=1.19.10 && <1.25

        >=1.19.10

        >=1.19.10

        >=1.19

        >=1.19

        >=1.11

        >=1.11

        CRI API

        v1

        v1

        v1alpha2

        v1alpha2

        v1alpha2

        Scylla OS

        >=5.0

        >=5.0

        >=5.0

        >=4.3

        >=4.3

        >=4.3

        >=4.3

        >=4.2

        >=4.2

        >=4.0

        >=4.0

        Scylla Enterprise

        >=2021.1

        >=2021.1

        >=2021.1

        >=2021.1

        >=2021.1

        >=2021.1

        >=2021.1

        >=2020.1

        >=2020.1

        >=2020.1

        >=2020.1

        Scylla Manager

        >=2.6

        >=2.6

        >=2.6

        >=2.2

        >=2.2

        >=2.2

        >=2.2

        >=2.2

        >=2.2

        >=2.2

        >=2.2

        Scylla Monitoring

        >=4.0

        >=4.0

        >=4.0

        >=3.0

        >=3.0

        >=1.0

        >=1.0

        >=1.0

        >=1.0

        >=1.0

        >=1.0

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/scylla-cluster-crd.html b/stable/scylla-cluster-crd.html new file mode 100644 index 00000000000..0955099b05c --- /dev/null +++ b/stable/scylla-cluster-crd.html @@ -0,0 +1,800 @@ + + + + + + + + + + + + + Scylla Cluster CRD | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Scylla Cluster CRD

        +

        Scylla database clusters can be created and configured using the clusters.scylla.scylladb.com custom resource definition (CRD).

        +

        Please refer to the the user guide walk-through for deployment instructions. +This page will explain all the available configuration options on the Scylla CRD.

        +
        +

        Sample

        +
        apiVersion: scylla.scylladb.com/v1
        +kind: ScyllaCluster
        +metadata:
        +  name: simple-cluster
        +  namespace: scylla
        +spec:
        +  version: 2.3.1
        +  repository: scylladb/scylla
        +  developerMode: true
        +  cpuset: false
        +  automaticOrphanedNodeCleanup: true
        +  repairs:
        +  - name: "weekly us-east-1 repair"
        +    intensity: "2"
        +    interval: "7d"
        +    dc: ["us-east-1"]
        +  backups:
        +  - name: "daily users backup"
        +    rateLimit: ["50"]
        +    location: ["s3:cluster-backups"]
        +    interval: "1d"
        +    keyspace: ["users"]
        +  - name: "weekly full cluster backup"
        +    rateLimit: ["50"]
        +    location: ["s3:cluster-backups"]
        +    interval: "7d"
        +  datacenter:
        +    name: us-east-1
        +    racks:
        +      - name: us-east-1a
        +        members: 3
        +        storage:
        +          capacity: 500G
        +          storageClassName: local-raid-disks
        +        resources:
        +          requests:
        +            cpu: 8
        +            memory: 32Gi
        +          limits:
        +            cpu: 8
        +            memory: 32Gi
        +        placement:
        +          nodeAffinity:
        +            requiredDuringSchedulingIgnoredDuringExecution:
        +              nodeSelectorTerms:
        +                - matchExpressions:
        +                  - key: failure-domain.beta.kubernetes.io/region
        +                    operator: In
        +                    values:
        +                      - us-east-1
        +                  - key: failure-domain.beta.kubernetes.io/zone
        +                    operator: In
        +                    values:
        +                      - us-east-1a
        +          tolerations:
        +            - key: role
        +              operator: Equal
        +              value: scylla-clusters
        +              effect: NoSchedule
        +
        +
        +
        +
        +

        Settings Explanation

        +
        +

        Cluster Settings

        +
          +
        • version: The version of Scylla to use. It is used as the image tag to pull.

        • +
        • agentVersion: The version of Scylla Manager Agent to use. It is used as the image tag to pull.

        • +
        • repository: Optional field. Specifies a custom image repo. If left unset, the official docker hub repo is used (scylladb/scylla).

        • +
        • agentRepository: Optional field. Specifies a custom Scylla Manager Agent image repo. If left unset, the official docker hub repo is used (scylladb/scylla).

        • +
        • developerMode: Optional field. If it’s true, then Scylla is started in developer mode. This setting is for shared test/dev environments.

        • +
        • cpuset: Optional field. If it’s true, then the operator will start Scylla with cpu pinning for maximum performance. For this to work, you need to set the kubelet to use the static cpu policy and only specify limits in resources.

        • +
        • automaticOrphanedNodeCleanup: Optional field. Controls if automatic orphan node cleanup should be performed.

        • +
        • alternator: Optional field. Defines Alternator configuration.

          +
            +
          • port: Port on which to bind to Alternator API.

          • +
          • writeIsolation: required Desired write isolation.

          • +
          +
        • +
        • genericUpgrade: Optional field. Defines GenericUpgrade configuration.

          +
            +
          • failureStrategy: specifies which logic is executed when upgrade failure happens. Currently only Retry is supported.

          • +
          • pollInterval: specifies how often upgrade logic polls on state updates. +Increasing this value should lower number of requests sent to the kube-apiserver, but it may affect +overall time spent during upgrade.

          • +
          +
        • +
        • datacenter: Datacenter definition.

        • +
        • sysctls: Optional field. Sysctl properties to be applied during initialization.

        • +
        • scyllaArgs: Optional field. Command line argument passed to Scylla container image. Note: not all Scylla versions support it.

        • +
        • network: Optional field. Allows to customize network parameters.

          +
            +
          • hostNetworking: controls if host networking should be enabled.

          • +
          • dnsPolicy: controls Scylla Pod DNS Policy. See details.

          • +
          +
        • +
        • repairs: Optional field. Repair tasks definitions. See Scylla Manager settings for details.

        • +
        • backups: Optional field. Repair tasks definitions. See Scylla Manager settings for details.

        • +
        +

        In the Scylla model, each cluster contains datacenters and each datacenter contains racks. At the moment, the operator only supports single datacenter setups.

        +
        +
        +

        Scylla Manager settings

        +

        Tasks are scheduled only when Scylla Manager is deployed in K8s cluster.

        +

        Repairs:

        +
          +
        • name - required - human readable name of the task. It must be unique across all tasks.

        • +
        • startDate - specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, +valid units are d, h, m, s (default “now”).

        • +
        • interval - Optional field. Task schedule interval e.g. 3d2h10m, valid units are d, h, m, s (default “0”).

        • +
        • numRetries - Optional field. The number of times a scheduled task will retry to run before failing (default 3).

        • +
        • dc - Optional field. A list of datacenter glob patterns, e.g. ["dc1", "!otherdc*"] used to specify the DCs to include or exclude from backup.

        • +
        • failFast - Optional field. Stop repair on first error.

        • +
        • intensity - Optional field. Specifies how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. +If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). +Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. +Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. +For Scylla clusters that do not support row-level repair, intensity can be a decimal between (0,1). +In that case it specifies percent of shards that can be repaired in parallel on a repair master node. +For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1. +Intensity is a number passed as string due to lack of support for float values in k8s controller runtime

        • +
        • parallel - Optional field. Specifies the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). +Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. +The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. +The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2.

        • +
        • keyspace - Optional field. A list of keyspace/tables glob patterns, e.g. ["keyspace", "!keyspace.table_prefix_*"] +used to include or exclude keyspaces from repair.

        • +
        • smallTableThreshold - Optional field. Enable small table optimization for tables of size lower than given threshold. +Supported units [B, MiB, GiB, TiB] (default "1GiB").

        • +
        +

        Backups:

        +
          +
        • name - required - human readable name of the task. It must be unique across all tasks.

        • +
        • startDate - Optional field. Specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, +valid units are d, h, m, s (default “now”).

        • +
        • interval - Optional field. task schedule interval e.g. 3d2h10m, valid units are d, h, m, s (default “0”).

        • +
        • numRetries - Optional field. the number of times a scheduled task will retry to run before failing (default 3).

        • +
        • dc - Optional field. A list of datacenter glob patterns, e.g. ["dc1","!otherdc*"] used to specify the DCs to include or exclude from backup.

        • +
        • keyspace - Optional field. A list of keyspace/tables glob patterns, e.g. ["keyspace","!keyspace.table_prefix_*"] used to include or exclude keyspaces from backup.

        • +
        • location - Optional field. A list of backup locations in the format [<dc>:]<provider>:<name> ex. s3:my-bucket. +The <dc>: part is optional and is only needed when different datacenters are being used to upload data to different locations. +<name> Optional field. must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. +The only supported storage at the moment are s3 and gcs.

        • +
        • rateLimit - Optional field. A list of megabytes (MiB) per second rate limits expressed in the format [<dc>:]<limit>. +The <dc>: part is optional and only needed when different datacenters need different upload limits. +Set to 0 for no limit (default 100).

        • +
        • retention - Optional field. The number of backups which are to be stored (default 3).

        • +
        • snapshotParallel - Optional field. A list of snapshot parallelism limits in the format [<dc>:]<limit>. +The <dc>: part is optional and allows for specifying different limits in selected datacenters. +If The <dc>: part is not set, the limit is global (e.g. ["dc1:2,5"]) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters.

        • +
        • uploadParallel - Optional field. A list of upload parallelism limits in the format [<dc>:]<limit>. +The <dc>: part is optional and allows for specifying different limits in selected datacenters. +If The <dc>: part is not set the limit is global (e.g. ["dc1:2,5"]) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters.

        • +
        +
        +
        +

        Datacenter Settings

        +
          +
        • name: Name of the datacenter. Usually, a datacenter corresponds to a region.

        • +
        • racks: List of racks for the specific datacenter.

        • +
        +
        +
        +

        Rack Settings

        +
          +
        • name: Name of the rack. Usually, a rack corresponds to an availability zone.

        • +
        • members: Number of Scylla members for the specific rack. (In Scylla documentation, they are called nodes. We don’t call them nodes to avoid confusion as a Scylla Node corresponds to a Kubernetes Pod, not a Kubernetes Node).

        • +
        • storage: Defines the specs of the underlying storage.

          +
            +
          • capacity: Capacity of the PersistentVolume to request.

          • +
          • storageClassName: Optional field. StorageClass of PersistentVolume to request.

          • +
          +
        • +
        • resources: Defines the CPU and RAM resources for the Scylla Pods.

          +
            +
          • requests: The minimum amount of resources needed to run a Scylla container.

            +
              +
            • cpu: CPU requests.

            • +
            • memory: RAM requests.

            • +
            +
          • +
          • limits: The maximum amount of resources that can be used by a Scylla container.

            +
              +
            • cpu: CPU limits.

            • +
            • memory: RAM limits.

            • +
            +
          • +
          +
        • +
        • agentResources: Optional field. Defines the CPU and RAM resources for the Scylla Manager Agent container. See resources for details.

        • +
        • volumes: Optional field. Defines volumes available in Scylla Pod. See details.

        • +
        • volumeMounts: Optional field. Defines which volumes will be attached to Scylla container.

        • +
        • agentVolumeMounts: Optional field. Defines which volumes will be attached to Agent container.

        • +
        • scyllaConfig: Optional field. name of custom config map which will be merged with Scylla config.

        • +
        • scyllaAgentConfig: Optional field. name of custom secret which will be merged with Scylla Manager Agent config.

        • +
        • placement: Optional field. Defines the placement of Scylla Pods. Has the following subfields:

          + +
        • +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/search.html b/stable/search.html new file mode 100644 index 00000000000..83a99fb8510 --- /dev/null +++ b/stable/search.html @@ -0,0 +1,552 @@ + + + + + + + + + + + + + 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 00000000000..41a1b5ee407 --- /dev/null +++ b/stable/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["contributing", "eks", "exposing", "generic", "gke", "helm", "index", "manager", "migration", "monitoring", "multidc/eks", "multidc/gke", "multidc/index", "multidc/multidc", "nodeoperations/automatic-cleanup", "nodeoperations/index", "nodeoperations/maintenance-mode", "nodeoperations/replace-node", "nodeoperations/restore", "nodeoperations/scylla-upgrade", "performance", "releases", "scylla-cluster-crd", "support/index", "support/known-issues", "support/must-gather", "support/overview", "support/troubleshooting/index", "support/troubleshooting/installation", "upgrade"], "filenames": ["contributing.md", "eks.md", "exposing.md", "generic.md", "gke.md", "helm.md", "index.rst", "manager.md", "migration.md", "monitoring.md", "multidc/eks.md", "multidc/gke.md", "multidc/index.rst", "multidc/multidc.md", "nodeoperations/automatic-cleanup.md", "nodeoperations/index.rst", "nodeoperations/maintenance-mode.md", "nodeoperations/replace-node.md", "nodeoperations/restore.md", "nodeoperations/scylla-upgrade.md", "performance.md", "releases.md", "scylla-cluster-crd.md", "support/index.rst", "support/known-issues.md", "support/must-gather.md", "support/overview.md", "support/troubleshooting/index.rst", "support/troubleshooting/installation.md", "upgrade.md"], "titles": ["Contributing to Scylla Operator", "Deploying Scylla on EKS", "Exposing ScyllaCluster", "Deploying Scylla on a Kubernetes Cluster", "Deploying Scylla on GKE", "Deploying Scylla stack using Helm Charts", "Scylla Operator Documentation", "Deploying Scylla Manager on a Kubernetes Cluster", "Version migrations", "Monitoring", "Build multiple Amazon EKS clusters with inter-Kubernetes networking", "Build multiple GKE clusters with inter-Kubernetes networking", "Deploying multi-datacenter ScyllaDB clusters in Kubernetes", "Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters", "Automatic cleanup and replacement in case when k8s node is lost", "Node operations using Scylla Operator", "Maintenance mode", "Replacing a Scylla node", "Restore from backup", "Upgrading version of Scylla", "Performance tuning", "Releases", "Scylla Cluster CRD", "Support", "Known issues", "Gathering data with must-gather", "Support overview", "Troubleshooting", "Troubleshooting installation issues", "Upgrade of Scylla Operator"], "terms": {"To": [0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 16, 17, 18, 19, 24, 26, 28, 29], "environ": [0, 2, 3, 5, 8, 13, 22, 25], "must": [0, 2, 3, 7, 13, 17, 19, 20, 21, 22, 23, 26, 29], "have": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 18, 19, 20, 25, 28, 29], "follow": [0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 18, 19, 21, 22, 24, 29], "go": [0, 3, 5, 8, 13, 17, 29], "1": [0, 1, 2, 3, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 20, 21, 22], "13": [0, 7], "make": [0, 3, 4, 5, 7, 8, 9, 13, 17, 18, 21, 25, 28, 29], "sure": [0, 3, 4, 5, 7, 8, 13, 17, 18, 21, 25, 28, 29], "gopath": 0, "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 28, 29], "set": [0, 2, 5, 6, 7, 9, 13, 18, 19, 20, 24, 25], "home": 0, "kustom": 0, "v3": 0, "0": [0, 2, 3, 4, 5, 7, 9, 10, 11, 13, 17, 18, 19, 21, 22, 25], "kubebuild": 0, "v2": 0, "3": [0, 1, 3, 5, 7, 13, 18, 19, 20, 21, 22], "docker": [0, 3, 5, 21, 22, 29], "git": [0, 3, 8, 21, 29], "client": [0, 3, 5, 8, 9, 13, 17], "instal": [0, 3, 6, 7, 8, 9, 10, 11, 13, 25, 27, 29], "github": [0, 3, 6, 9, 21, 25], "account": [0, 4], "all": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 18, 19, 20, 22, 25], "depend": [0, 2, 8, 16, 17, 20, 21, 22, 25], "dep": 0, "simpli": [0, 3, 5, 8, 16, 19], "run": [0, 1, 4, 5, 6, 7, 8, 9, 13, 17, 18, 19, 20, 22, 29], "sh": [0, 1, 4], "from": [0, 1, 2, 3, 4, 5, 8, 9, 10, 13, 15, 16, 17, 19, 20, 21, 22, 25, 29], "browser": 0, "navig": 0, "http": [0, 1, 3, 5, 7, 9, 25, 29], "com": [0, 1, 2, 3, 4, 5, 8, 9, 13, 18, 20, 22, 25, 29], "scylladb": [0, 2, 3, 5, 6, 8, 9, 18, 20, 21, 22, 25, 26, 29], "click": 0, "button": 0, "open": [0, 2, 3, 6, 7, 18], "consol": 0, "window": 0, "do": [0, 3, 7, 9, 10, 11, 16, 22, 26, 28, 29], "repo": [0, 5, 8, 22, 29], "path": [0, 3, 8, 13, 18, 25, 29], "mkdir": 0, "p": [0, 3, 4, 8, 13, 18, 19, 29], "src": 0, "local": [0, 9, 10, 13, 17, 22], "cd": [0, 1, 3, 4], "where": [0, 1, 4, 8, 18, 19, 28], "user": [0, 3, 4, 6, 7, 8, 9, 16, 18, 19, 20, 22, 25, 28, 29], "name": [0, 1, 3, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 20, 22, 25, 29], "first": [0, 1, 3, 4, 5, 7, 8, 9, 18, 19, 22, 29], "you": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 22, 25, 28, 29], "need": [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 13, 17, 18, 19, 20, 22, 25, 28, 29], "list": [0, 3, 4, 7, 8, 11, 18, 22, 29], "verifi": [0, 3, 13, 17], "wa": [0, 3, 5, 7, 8, 10, 17, 18, 29], "ad": [0, 3, 6, 10], "v": [0, 25], "now": [0, 1, 3, 4, 7, 8, 10, 11, 13, 22], "should": [0, 2, 3, 5, 7, 8, 9, 10, 11, 13, 17, 19, 20, 22], "least": [0, 4, 5, 13, 20, 25], "origin": [0, 13], "can": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 19, 20, 22, 25, 26, 28], "also": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 25], "other": [0, 2, 4, 5, 6, 7, 9, 10, 11, 13, 17, 20, 21, 22, 25], "collabor": 0, "contributor": 0, "featur": [0, 18, 20], "bug": [0, 18, 21, 26], "fix": [0, 18, 21, 24], "pr": 0, "us": [0, 1, 2, 3, 4, 6, 7, 8, 10, 11, 17, 18, 19, 20, 21, 22, 25, 28, 29], "makefil": 0, "command": [0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 22, 24, 25], "chang": [0, 3, 4, 5, 7, 8, 9, 13, 19, 22, 29], "img": 0, "variabl": [0, 13, 25], "repositori": [0, 3, 22, 29], "access": [0, 2, 7, 18], "push": 0, "wait": [0, 3, 5, 8, 13, 18, 19, 29], "imag": [0, 4, 8, 11, 19, 20, 21, 22, 29], "built": [0, 2, 10, 11], "upload": [0, 22], "new": [0, 3, 4, 6, 7, 8, 9, 10, 13, 17, 19, 20, 21, 29], "base": [0, 5, 20], "start": [0, 1, 3, 7, 10, 18, 19, 20, 22], "work": [0, 1, 4, 5, 8, 10, 11, 13, 20, 21, 22], "ensur": [0, 3, 8], "ar": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 20, 21, 22, 25, 26, 28, 29], "up": [0, 2, 5, 6, 8, 9, 13, 17, 19, 20, 29], "date": [0, 5, 7, 13, 21, 22, 29], "latest": [0, 1, 6, 21, 25], "fetch": 0, "off": [0, 3, 16, 19, 21, 29], "master": [0, 21, 22], "give": [0, 3, 4, 7, 21], "simpl": [0, 2, 3, 5, 7, 8, 16, 17, 19, 22, 29], "descript": [0, 5], "gener": [0, 1, 2, 3, 4, 7, 8, 9, 19, 29], "two": [0, 2, 5, 7, 8, 10, 11, 13, 18, 19, 20, 29], "three": [0, 5, 7], "word": [0, 13], "separ": [0, 1, 2, 4, 8, 10, 20], "dash": [0, 22], "without": [0, 2, 4, 5, 9, 25], "number": [0, 3, 22, 29], "checkout": [0, 8, 29], "b": [0, 4, 11, 13, 16, 22], "readi": [0, 3, 5, 7, 8, 10, 11, 16, 17, 19, 29], "dure": [0, 13, 19, 22, 29], "lifecycl": [0, 13], "keep": [0, 1, 4], "As": [0, 1, 4, 7, 10, 13, 18, 25], "team": 0, "rebas": 0, "top": 0, "thi": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 16, 17, 18, 19, 20, 21, 22, 24, 25, 28, 29], "avoid": [0, 22, 25, 28], "unnecessari": 0, "merg": [0, 2, 13, 18, 19, 21, 22], "clean": 0, "whenev": 0, "never": [0, 29], "want": [0, 1, 2, 3, 4, 5, 7, 10, 11, 18, 29], "alwai": [0, 3, 16, 20, 25], "otherwis": [0, 9, 10, 21], "end": [0, 8, 9, 18, 21], "If": [0, 1, 3, 4, 5, 7, 8, 9, 13, 19, 22, 24, 25, 28], "ani": [0, 2, 4, 5, 8, 10, 11, 18, 20, 21, 22], "modifi": [0, 3, 4, 11, 19, 28], "file": [0, 3, 4, 5, 8, 10, 25, 28, 29], "stash": 0, "them": [0, 1, 2, 3, 4, 5, 8, 9, 10, 13, 20, 22, 25, 29], "save": [0, 3, 8, 10, 13, 19, 25, 29], "u": [0, 1, 3, 4, 5, 7, 8, 10, 11, 13, 16, 17, 18, 19, 20, 22, 26], "some": [0, 2, 3, 5, 7, 17, 21, 25, 28], "veri": [0, 5, 8, 25, 29], "power": [0, 20], "understand": [0, 8, 26], "how": [0, 1, 2, 4, 5, 7, 9, 17, 18, 22, 25, 28], "els": [0, 9], "risk": 0, "lose": [0, 14], "read": [0, 1, 3, 4, 5, 8], "about": [0, 1, 2, 3, 4, 5, 11, 20], "document": [0, 1, 2, 3, 4, 5, 7, 10, 11, 13, 22], "well": [0, 1, 3, 4, 7, 8, 9], "worth": 0, "In": [0, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20, 22, 25, 29], "nutshel": 0, "doe": [0, 3, 5, 7, 13], "unwind": 0, "remov": [0, 3, 5, 8, 13, 14, 16, 19, 25, 29], "temporarili": 0, "The": [0, 1, 2, 3, 4, 6, 7, 9, 10, 11, 13, 20, 21, 22, 24, 25], "re": [0, 8, 29], "appli": [0, 1, 3, 4, 5, 7, 8, 9, 13, 20, 22, 24, 25, 29], "one": [0, 2, 3, 5, 7, 8, 11, 13, 14, 17, 19, 22, 25, 29], "conflict": 0, "prompt": 0, "befor": [0, 8, 9, 19, 21, 22, 25, 28, 29], "continu": [0, 19], "output": [0, 3, 7, 8, 11, 13, 18], "close": [0, 5], "It": [0, 1, 2, 3, 4, 5, 10, 11, 13, 19, 22], "tell": 0, "complet": [0, 3, 9, 17], "when": [0, 1, 2, 3, 4, 7, 8, 9, 11, 13, 15, 16, 18, 19, 20, 21, 22, 25, 26, 28], "done": [0, 1, 3, 4, 7, 18, 25], "see": [0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 18, 20, 22], "onc": [0, 1, 3, 4, 5, 7, 10, 11, 19, 29], "implement": [0, 13], "unit": [0, 22], "test": [0, 7, 9, 21, 22, 28], "pass": [0, 2, 4, 21, 22, 28], "integr": [0, 6, 13], "order": [0, 2, 3, 4, 7, 13, 29], "requir": [0, 1, 2, 3, 4, 10, 11, 13, 18, 20, 21, 22, 24, 26, 28, 29], "again": [0, 8, 9, 16], "prepar": [0, 12, 13], "minim": [0, 5], "logic": [0, 2, 22], "so": [0, 2, 3, 4, 5, 9, 10, 11, 13, 20, 29], "we": [0, 1, 2, 3, 4, 5, 7, 8, 9, 17, 18, 20, 21, 22, 25, 28, 29], "maintain": [0, 21], "most": [0, 1, 3, 4, 5, 9, 13, 20, 22], "commonli": 0, "includ": [0, 5, 11, 22, 26, 28], "singl": [0, 3, 5, 7, 13, 22], "squash": 0, "although": [0, 5, 8, 9, 10, 11, 13], "sometim": [0, 3, 25], "multipl": [0, 2, 3, 7, 8, 12], "inspect": 0, "determin": [0, 25], "log": [0, 3, 7, 19, 22], "edit": [0, 1, 3, 4, 7], "even": [0, 19], "reorder": 0, "exampl": [0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 16, 18, 19, 20, 25, 29], "last": 0, "5": [0, 2, 7, 13, 18, 19, 20, 21, 22], "tool": [0, 1, 9, 10, 11, 13, 25, 26], "head": 0, "pleas": [0, 5, 20, 22, 25, 28, 29], "line": [0, 10, 11, 13, 22], "summari": 0, "would": [0, 3, 7, 11, 17], "like": [0, 3, 6, 7, 8, 9, 17, 20, 21, 25], "prefix": 0, "relev": 0, "directori": [0, 25, 29], "colon": 0, "changelog": 0, "get": [0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 25, 29], "made": [0, 2, 21], "look": [0, 3, 5, 8, 13, 25], "just": [0, 1, 3, 4], "good": [0, 2, 5], "more": [0, 1, 2, 3, 4, 5, 9, 10, 11, 13, 17, 20, 22, 25, 26, 28], "sai": 0, "enter": [0, 5, 17, 19], "blank": 0, "carri": [0, 13], "rememb": [0, 3], "why": 0, "itself": [0, 5, 7, 16], "show": [0, 3, 19, 21], "what": [0, 2, 3, 5, 7, 8, 9, 19, 25, 26], "write": [0, 3, 22], "better": [0, 4], "than": [0, 2, 3, 8, 17, 22, 25], "less": [0, 8, 9, 29], "compar": [0, 8], "behaviour": 0, "after": [0, 1, 3, 4, 5, 7, 17], "imagin": 0, "yourself": 0, "12": [0, 7, 18, 21], "month": 0, "time": [0, 5, 7, 8, 17, 18, 21, 22], "ve": 0, "forgotten": 0, "everyth": [0, 1, 3, 4, 5, 19], "did": 0, "speed": 0, "quickli": 0, "an": [0, 2, 3, 5, 6, 10, 11, 19, 20, 21, 22, 25, 26, 28, 29], "issu": [0, 6, 7, 8, 19, 23, 25, 27, 29], "1234": 0, "subject": [0, 20], "fit": [0, 2], "don": [0, 1, 2, 4, 5, 22, 25], "t": [0, 1, 2, 3, 4, 5, 7, 8, 17, 18, 20, 21, 22, 25, 28, 29], "associ": [0, 3, 7, 8, 10, 11], "put": 0, "link": [0, 24], "here": [0, 3, 25, 29], "short": [0, 8], "sidecar": [0, 3, 5, 8, 29], "reconcil": [0, 9], "loop": 0, "And": [0, 5], "longer": [0, 3, 4, 13, 17, 18], "api": [0, 3, 7, 9, 13, 21, 22, 25, 28], "support": [0, 2, 3, 5, 6, 7, 13, 18, 19, 22, 25, 28, 29], "host": [0, 7, 9, 13, 17, 22], "network": [0, 2, 6, 12, 17, 20, 22, 28], "crd": [0, 3, 5, 6, 7, 8, 20, 29], "ha": [0, 2, 3, 4, 10, 13, 18, 21, 22], "properti": [0, 2, 3, 22], "select": [0, 2, 3, 13, 22], "apropri": 0, "dn": [0, 2, 3, 9, 13, 16, 17, 22], "polici": [0, 1, 2, 4, 5, 20, 22], "recent": 0, "obviou": 0, "tab": 0, "track": [0, 3, 7], "automat": [0, 3, 4, 7, 11, 15, 21, 22, 29], "guid": [1, 3, 4, 5, 7, 8, 10, 11, 13, 22, 29], "focus": [1, 4], "improv": 1, "perform": [1, 3, 4, 6, 14, 22], "trick": 1, "won": [1, 2, 20, 25], "differ": [1, 2, 3, 5, 7, 10, 11, 13, 20, 22], "machin": [1, 3, 4, 9, 11, 25], "tier": 1, "kubelet": [1, 4, 20, 22], "static": [1, 4, 8, 20, 22], "cpu": [1, 3, 4, 5, 13, 18, 20, 22], "sdd": [1, 4], "disk": [1, 3, 4, 11, 17, 20, 22], "raid0": [1, 4], "maximum": [1, 4, 22], "same": [1, 2, 3, 4, 5, 7, 8, 13, 19, 20, 21, 22], "tri": [1, 4], "step": [1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 18, 25, 29], "accord": [1, 3, 4, 8, 10, 19], "your": [1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20, 24, 25, 28, 29], "prefer": [1, 4, 10, 11], "eks_region": 1, "east": [1, 3, 5, 7, 8, 10, 13, 17, 18, 19, 20, 22], "eks_zon": 1, "1a": [1, 3, 7, 8, 10, 13, 17, 18, 19, 20, 22], "1b": [1, 5, 10, 13], "1c": [1, 10, 13], "insid": [1, 3, 4, 16], "folder": [1, 4, 25], "z": [1, 4, 21, 25], "r": 1, "benchmark": [1, 4], "cassandra": [1, 4], "stress": [1, 4], "export": [1, 4, 25], "option": [1, 3, 4, 5, 7, 13, 20, 22, 25], "own": [1, 4, 5, 13, 17], "cluster_nam": [1, 3, 4], "demo": [1, 4, 17], "For": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 16, 20, 22], "ll": [1, 4, 18, 25], "A": [1, 2, 3, 4, 5, 9, 10, 11, 13, 22, 29], "nodegroup": [1, 10], "i3": 1, "2xlarg": 1, "pod": [1, 2, 3, 4, 5, 7, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22, 25, 28], "These": [1, 2, 4, 20, 29], "onli": [1, 3, 8, 10, 11, 13, 19, 20, 21, 22, 25, 29], "accept": [1, 21], "toler": [1, 13, 22], "pool": [1, 4, 11, 13, 17, 20], "instancetyp": 1, "desiredcapac": 1, "label": [1, 3, 4, 9, 13, 16, 17, 20], "type": [1, 4, 5, 8, 9, 10, 11, 13, 17, 18, 19, 20, 21], "taint": [1, 4], "role": [1, 3, 4, 8, 13, 22], "noschedul": [1, 4, 13, 22], "ssh": [1, 7, 24], "allow": [1, 3, 5, 9, 10, 11, 13, 16, 19, 20, 22, 28], "true": [1, 3, 5, 7, 9, 13, 18, 22, 29], "kubeletextraconfig": 1, "cpumanagerpolici": [1, 4], "4": [1, 3, 4, 5, 7, 18, 19, 20, 21], "c4": 1, "later": [1, 4], "larg": [1, 25], "monitor": [1, 4, 6, 13, 21], "stack": [1, 4, 6, 9], "sever": [1, 2, 10, 11, 28], "eksctl": [1, 10], "doc": [1, 3, 18, 20, 28], "aw": [1, 2, 10], "amazon": [1, 12, 13], "userguid": 1, "html": 1, "kubectl": [1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 16, 17, 18, 19, 20, 25], "kubernet": [1, 2, 5, 6, 8, 9, 21, 22, 25, 28], "io": [1, 2, 3, 9, 10, 13, 21, 22, 25, 29], "task": [1, 3, 6, 13, 18, 22], "refer": [1, 3, 4, 5, 8, 9, 10, 11, 13, 21, 22, 29], "its": [1, 3, 4, 7, 8, 10, 11, 13], "except": [1, 4], "develop": [1, 4, 7, 9, 22], "mode": [1, 4, 7, 11, 15, 19, 22, 25], "storag": [1, 3, 4, 5, 9, 13, 18, 20, 22, 29], "xf": [1, 4, 13], "filesystem": [1, 4, 16], "nvme": [1, 4], "cloud": [1, 2, 3, 4, 7, 9, 11, 13], "provid": [1, 2, 3, 4, 5, 9, 10, 13, 20, 22, 26, 28], "usual": [1, 2, 4, 9, 21, 22], "come": [1, 3, 4, 7, 20], "individu": [1, 4], "devic": [1, 4, 20], "full": [1, 3, 4, 7, 8, 17, 19, 22], "capac": [1, 4, 5, 13, 18, 20, 22], "togeth": [1, 4], "form": [1, 4, 25], "raid": [1, 4, 22], "arrai": [1, 4], "those": [1, 3, 4, 20], "nodeconfig": [1, 4, 20], "necessari": [1, 3, 4, 9, 10, 11, 13, 25], "creation": [1, 4, 7, 21], "optim": [1, 4, 20, 22], "tune": [1, 4, 6], "section": [1, 2, 3, 4, 10, 11, 25, 26], "": [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 20, 22, 25, 28, 29], "let": [1, 4, 5, 7, 13, 25], "take": [1, 3, 4, 17, 18, 19, 20, 22, 25], "care": [1, 2, 4], "abov": [1, 3, 4, 5, 7, 9, 10, 11, 29], "server": [1, 3, 4, 7, 9, 13, 29], "side": [1, 4, 9, 13, 29], "f": [1, 3, 4, 5, 7, 8, 9, 10, 13, 29], "alpha": [1, 4, 21], "yaml": [1, 3, 4, 5, 7, 8, 9, 10, 13, 25, 29], "afterward": [1, 4], "capabl": [1, 2, 3, 4, 13], "dynam": [1, 4], "provis": [1, 2, 3, 4, 5, 13], "persistentvolum": [1, 3, 4, 22], "mount": [1, 3, 4, 25], "earlier": [1, 4, 10, 13], "over": [1, 4, 13, 17, 19], "n": [1, 3, 4, 5, 7, 8, 9, 13, 16, 17, 18, 19, 21, 22, 25, 29], "csi": [1, 4], "driver": [1, 2, 3, 4], "common": [1, 3, 4, 5, 7, 8, 20, 25, 28, 29], "storageclass_xf": [1, 4], "describ": [1, 3, 4, 7, 8, 10, 11, 13, 18, 19, 29], "launch": [1, 4], "highli": [1, 3, 4], "instruct": [1, 3, 4, 5, 8, 10, 22], "found": [1, 3, 4], "experi": [1, 4], "explain": [2, 9, 10, 11, 20, 22], "oper": [2, 7, 8, 13, 14, 16, 17, 18, 19, 20, 21, 22, 25, 26, 28], "setup": [2, 3, 9, 10, 11, 13, 22, 28], "variou": [2, 3], "configur": [2, 7, 13, 20, 22, 28, 29], "independ": [2, 13, 28], "version": [2, 3, 4, 5, 6, 7, 9, 13, 15, 18, 20, 21, 22, 29], "2023": [2, 21], "enterpris": [2, 6, 7, 21], "2": [2, 3, 4, 5, 7, 8, 10, 11, 13, 16, 17, 18, 19, 20, 21, 22], "sourc": [2, 5, 6, 7, 10, 11, 18, 29], "exposeopt": [2, 9, 13], "specifi": [2, 3, 5, 10, 13, 22], "creat": [2, 5, 7, 8, 9, 13, 18, 20, 22, 25, 29], "equival": 2, "apivers": [2, 8, 9, 10, 13, 18, 20, 22, 29], "scylla": [2, 8, 9, 10, 11, 14, 16, 18, 20, 21, 25, 26, 28], "v1": [2, 5, 7, 9, 13, 18, 20, 21, 22], "kind": [2, 8, 9, 10, 13, 18, 20, 22, 29], "spec": [2, 3, 5, 7, 8, 9, 13, 18, 19, 20, 22, 29], "nodeservic": [2, 13], "broadcastopt": [2, 13], "cover": [2, 20], "everi": [2, 3, 13, 19, 21], "field": [2, 3, 5, 9, 13, 19, 22, 25], "control": [2, 4, 7, 8, 9, 13, 19, 22, 28, 29], "serv": [2, 3, 5, 9, 10, 11, 13, 28], "dedic": [2, 5, 7, 10, 11, 13, 20, 25, 26], "manag": [2, 4, 6, 8, 10, 11, 17, 18, 20, 21, 25, 29], "each": [2, 3, 4, 5, 7, 8, 10, 11, 13, 19, 20, 22, 29], "within": [2, 20, 25], "addition": [2, 13], "defin": [2, 3, 5, 7, 13, 22], "custom": [2, 6, 7, 9, 10, 11, 22], "annot": [2, 9], "incorpor": 2, "which": [2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 17, 18, 19, 20, 22, 29], "might": [2, 8, 17], "further": 2, "tweak": [2, 3], "relat": [2, 6, 13, 25], "object": [2, 3, 9, 13, 29], "selector": [2, 3, 29], "point": [2, 4, 8, 9, 13, 19, 25], "particular": [2, 3, 5, 13, 19, 21], "Such": 2, "doesn": [2, 3, 4, 28, 29], "addit": [2, 5, 7, 8, 11, 29], "ip": [2, 3, 5, 8, 9, 11, 13, 17, 24], "address": [2, 9, 11, 13, 17], "intern": [2, 5, 7], "record": [2, 9], "resolv": [2, 7, 19], "back": [2, 16, 17, 19], "specif": [2, 3, 5, 10, 11, 13, 20, 22, 28, 29], "routabl": 2, "direct": [2, 3, 9, 11], "traffic": [2, 10, 11, 28], "On": [2, 20, 24], "platform": [2, 3, 9, 10, 11, 12], "extern": [2, 5, 8, 9, 17, 25], "load": [2, 13, 16, 17, 22], "balanc": [2, 16], "case": [2, 3, 8, 10, 13, 17, 20, 22, 25, 28, 29], "mai": [2, 9, 13, 14, 16, 17, 19, 20, 21, 22, 25, 29], "reachabl": [2, 9], "public": 2, "via": [2, 3, 5], "kei": [2, 3, 7, 13, 22, 25], "valu": [2, 3, 4, 5, 8, 10, 11, 13, 18, 19, 22], "pair": [2, 3], "through": [2, 3, 5, 10, 11, 13, 22], "entir": [2, 3, 13, 20], "ek": [2, 6, 12, 13], "beta": [2, 21, 22], "scheme": [2, 29], "backend": 2, "protocol": [2, 10], "tcp": [2, 5, 8, 11, 17], "gke": [2, 3, 6, 12, 13, 17], "check": [2, 3, 6, 7, 8, 17, 18, 19, 20, 25, 29], "regard": [2, 8, 11, 13], "learn": [2, 10, 26], "avail": [2, 3, 4, 5, 7, 9, 13, 17, 18, 19, 20, 22, 25, 29], "superset": 2, "impli": 2, "contain": [2, 4, 5, 8, 11, 18, 19, 21, 22, 25, 26, 29], "alloc": [2, 5, 11], "thei": [2, 3, 7, 13, 22, 25], "propag": [2, 3, 8, 13], "externaltrafficpolici": 2, "internaltrafficpolici": 2, "loadbalancerclass": 2, "allocateloadbalancernodeport": 2, "my": [2, 7, 22], "class": [2, 3, 20], "being": [2, 3, 7, 13, 16, 17, 19, 21, 22], "becaus": [2, 3, 7, 13, 17, 25], "help": [2, 3, 6, 25, 26], "cost": 2, "reliabl": 2, "latenc": 2, "secur": [2, 3], "metric": [2, 3, 5], "taken": [2, 18, 19], "By": [2, 4, 5, 20, 22, 25], "default": [2, 3, 4, 5, 7, 13, 17, 18, 20, 22, 24, 25], "statu": [2, 3, 5, 6, 7, 8, 9, 10, 13, 17, 18, 19, 29], "assign": [2, 20], "ingress": [2, 11, 28], "ipaddress": 2, "hostnam": [2, 13], "scenario": 2, "commun": [2, 10, 11, 13], "anoth": [2, 8, 28], "definit": [2, 3, 4, 5, 6, 7, 8, 19, 22, 29], "both": [2, 3, 5, 10, 11, 18], "deploi": [2, 6, 22, 29], "talk": [2, 7, 20, 25], "outsid": [2, 9], "assum": [2, 9, 13, 25], "subnet": [2, 10], "directli": [2, 11], "exclus": [2, 20], "distinct": [2, 10, 11, 13], "interconnect": [2, 10, 11, 12], "facilit": 2, "inter": [2, 12, 13], "connect": [2, 3, 7, 10], "assumpt": 2, "enabl": [2, 3, 4, 7, 10, 11, 13, 14, 16, 19, 22, 24], "establish": [2, 3, 10, 11, 29], "page": [2, 11, 22, 29], "know": 2, "whether": [2, 5, 20, 25], "reach": [2, 7, 9, 19, 28], "sinc": [2, 13], "suffici": 2, "been": [2, 3], "lb": 2, "discov": [2, 13], "resid": [2, 11], "rout": [2, 9], "consequ": 2, "complex": 2, "upon": [2, 10, 11], "ones": [2, 10, 29], "mean": [3, 8], "ideal": 3, "best": 3, "fast": 3, "extra": [3, 25], "detail": [3, 7, 9, 13, 20, 22], "helm": [3, 6, 9, 21], "stabl": [3, 5, 29], "daunt": 3, "error": [3, 4, 7, 19, 22, 25], "prone": 3, "fortun": 3, "wai": [3, 4, 7, 8, 9, 25], "life": [3, 17], "easier": [3, 8, 9, 29], "minikub": [3, 5], "breez": 3, "littl": 3, "bit": [3, 5], "resourc": [3, 6, 7, 8, 9, 10, 11, 13, 14, 18, 20, 22, 28, 29], "6": [3, 18, 20, 21, 22], "Then": [3, 4, 5, 10, 11, 19], "awar": 3, "eval": 3, "env": [3, 25], "manifest": [3, 13, 29], "clone": 3, "either": [3, 5, 7], "upsteam": [3, 5], "self": [3, 5], "sign": [3, 5, 8], "certif": [3, 5, 9, 18], "until": [3, 5, 8, 18, 19, 29], "condit": [3, 5, 8, 9, 13, 18, 20, 29], "issuer": 3, "rollout": [3, 8, 9, 29], "deploy": [3, 5, 7, 9, 11, 12, 13, 18, 19, 22, 29], "app": [3, 5, 9, 13, 18, 19, 29], "webhook": [3, 27, 29], "namespac": [3, 5, 7, 8, 13, 18, 20, 22, 29], "instanc": [3, 4, 5, 7, 8, 9, 10, 11, 13], "feel": [3, 25], "free": [3, 4, 25], "brows": 3, "repres": [3, 13], "our": [3, 8, 13, 20, 21, 25, 26, 29], "below": [3, 7, 8, 9, 10, 11, 13, 18, 20, 22], "import": [3, 4, 21], "successfulli": [3, 9], "extend": [3, 28], "citizen": 3, "nativ": [3, 11], "easi": 3, "someth": [3, 7, 16, 25], "restart": [3, 5, 7, 8, 13, 17, 18, 19, 29], "ag": [3, 5, 7, 8, 17, 29], "9m49": 3, "7m43": 3, "6m46": 3, "note": [3, 7, 9, 22, 29], "pattern": [3, 5, 22, 25], "datacenter_nam": 3, "rack_nam": 3, "instance_numb": 3, "attach": [3, 4, 8, 17, 22, 25, 26], "pick": [3, 13], "resembl": [3, 11], "find": [3, 5, 9, 19, 28, 29], "servic": [3, 5, 8, 9, 11, 16, 17, 28], "inconsequenti": 3, "anyth": 3, "desir": [3, 5, 7, 19, 22], "member": [3, 5, 7, 8, 13, 18, 19, 20, 22], "entri": 3, "l": [3, 5, 7, 8, 9, 18, 25], "state": [3, 5, 7, 9, 13, 17, 19, 22, 25], "current": [3, 5, 6, 9, 10, 11, 13, 19, 22, 25, 28], "squeez": 3, "out": [3, 6, 8, 13, 19, 29], "emploi": 3, "agentvers": [3, 13, 18, 20, 22], "cpuset": [3, 13, 22], "hostnetwork": [3, 22, 28], "result": [3, 8, 22], "sysctl": [3, 13, 22], "increas": [3, 22], "event": 3, "asynchron": 3, "process": [3, 4, 10, 11, 13, 16, 19, 20, 29], "linux": 3, "aio": [3, 13], "max": [3, 13], "nr": [3, 13], "2097152": [3, 13], "instead": [3, 28], "regular": [3, 7], "small": [3, 7, 22], "developermod": [3, 18, 22], "datacent": [3, 5, 6, 7, 10, 11, 17, 18, 20, 25], "port": [3, 5, 8, 9, 10, 17, 18, 22, 29], "8000": 3, "writeisol": [3, 22], "only_rmw_uses_lwt": 3, "whichev": 3, "isol": [3, 22], "forbid_rmw": 3, "between": [3, 10, 11, 22], "level": [3, 7, 22], "cql": [3, 7, 18], "pure": 3, "cqlsh": 3, "shell": [3, 8], "exec": [3, 7, 13, 17, 18, 25], "keyspac": [3, 7, 18, 19, 22], "convent": 3, "python": [3, 20], "svc": [3, 7, 8, 9, 16, 17], "session": 3, "plain": 3, "configmap": 3, "rack": [3, 5, 6, 7, 13, 17, 18, 19, 20], "call": [3, 4, 18, 20, 22, 26, 28, 29], "rest": [3, 7, 25], "config": [3, 4, 7, 10, 11, 13, 22, 25], "statefulset": [3, 5, 8, 9, 19, 29], "rackdc": 3, "tmp": 3, "o": [3, 8, 9, 21, 25], "dry": 3, "replac": [3, 6, 8, 9, 13, 15, 18, 25, 29], "overrid": 3, "prefer_loc": 3, "dc_suffix": 3, "authent": [3, 25], "adjust": [3, 9, 10, 11, 13, 22, 25], "system_auth": [3, 7], "replic": [3, 22], "factor": [3, 22, 25], "node": [3, 5, 6, 7, 8, 9, 16, 18, 19, 22], "inform": [3, 9, 10, 11, 13, 19, 26, 28], "kept": 3, "equal": [3, 13, 20, 22], "fail": [3, 7, 9, 17, 18, 22, 24], "whose": 3, "deni": [3, 11], "product": [3, 7, 8, 9, 13], "networktopologystrategi": 3, "c": [3, 11, 13, 17, 18], "e": [3, 22, 25, 29], "alter": 3, "WITH": 3, "replication_factor": 3, "second": [3, 22], "main": [3, 5, 7, 13], "endpoint": 3, "interact": [3, 16], "thing": 3, "backup": [3, 6, 7, 15, 22, 29], "secret": [3, 5, 9, 13, 22, 25], "popul": 3, "content": [3, 4, 5, 18, 21], "copi": [3, 25], "auto": 3, "empti": [3, 18], "decod": 3, "roll": [3, 5, 6, 8, 13, 18, 19, 29], "prometheu": [3, 5, 6, 7], "grafana": [3, 6], "exist": [3, 7, 8, 13, 19, 21, 25, 29], "introduc": [3, 9, 13, 20], "updat": [3, 5, 7, 9, 11, 22, 29], "add": [3, 5, 7, 8, 11, 13, 16, 17, 18, 29], "append": 3, "choos": [3, 6, 13, 15], "uniqu": [3, 13, 22], "down": [3, 6, 13, 17], "zero": [3, 19], "retriev": [3, 11, 25], "happen": [3, 19, 22], "passwordauthent": 3, "manual": [3, 4, 8, 9, 11, 13, 18, 19, 25, 28, 29], "usernam": [3, 9], "password": [3, 7, 9], "new_replication_factor": 3, "recommend": [3, 9, 13, 29], "along": 3, "mini": 3, "cli": [3, 5, 7, 11], "job": [3, 21, 22], "against": [3, 10, 11], "core": [3, 4, 20], "count": [3, 4, 7], "10": [3, 5, 7, 8, 10, 11, 13, 17, 21], "50": [3, 22], "000": 3, "throttl": [3, 20], "throughput": 3, "30": 3, "op": [3, 8, 13, 18], "sec": 3, "total": 3, "300": 3, "hack": 3, "cass": 3, "gen": 3, "py": 3, "num": [3, 4, 7, 11], "memori": [3, 5, 13, 18, 20, 22], "20g": 3, "50000000": 3, "limit": [3, 5, 7, 13, 18, 20, 22], "30000": 3, "script": [3, 4, 20], "proper": 3, "argument": [3, 7, 22, 25], "h": [3, 22], "usag": 3, "num_job": 3, "scylla_vers": 3, "thread": 3, "per": [3, 22], "connections_per_host": 3, "print": [3, 19], "stdout": 3, "nodeselector": [3, 20], "templat": [3, 8, 9, 13, 18, 29], "messag": [3, 7, 19], "exit": 3, "gb": 3, "ie": 3, "2g": 3, "10000000": 3, "rate": [3, 22], "certain": 3, "eg": 3, "while": 3, "finish": [3, 18], "delet": [3, 7, 8, 17, 19, 29], "walk": [3, 10, 11, 13, 22], "destroi": [3, 7, 13], "data": [3, 4, 7, 9, 13, 17, 18, 19, 22, 23, 29], "examin": [3, 7], "ok": 3, "persist": [4, 7], "guarante": [4, 20], "gcp_user": 4, "gcloud": [4, 11], "format": [4, 7, 11, 19, 22], "gcp_project": 4, "project": [4, 6], "gcp_zone": 4, "west1": [4, 11], "yanniszark": 4, "arrikto": 4, "226716": 4, "zone": [4, 6, 13, 22], "ex": [4, 22], "region": [4, 10, 11, 13, 22], "gcp_region": 4, "cluster_vers": 4, "validmastervers": 4, "systemconfig": 4, "kubeletconfig": 4, "nodepool": 4, "n1": [4, 11], "standard": [4, 11, 28], "8": [4, 7, 9, 11, 21, 22], "purpos": [4, 25], "pd": [4, 11], "ssd": [4, 11], "size": [4, 11, 17, 18, 22], "20": [4, 7, 11, 21], "ubuntu_containerd": [4, 11], "system": [4, 8, 19, 29], "stackdriv": 4, "autoupgrad": [4, 11], "autorepair": [4, 11], "32": 4, "raw": [4, 25], "block": [4, 28], "disabl": [4, 5, 11, 16, 18, 19, 24], "upgrad": [4, 5, 6, 8, 15, 21, 22], "repair": [4, 6, 7, 17, 18, 22], "hard": 4, "timeout": [4, 5, 7, 8, 9], "respect": 4, "pdb": 4, "forc": 4, "comput": [4, 11], "At": [4, 8, 19, 22], "handl": 4, "rbac": 4, "permiss": [4, 7, 8], "credenti": [4, 7, 9, 18], "clusterrolebind": [4, 25], "easiest": 4, "obtain": 4, "gcp": [4, 11], "iam": 4, "web": 4, "interfac": [4, 11], "bind": [4, 22], "clusterrol": [4, 8, 25], "sed": [4, 8, 29], "g": [4, 8, 22, 29], "inject": 4, "match": [4, 9, 20, 21], "compon": [5, 7, 9], "k8": [5, 6, 7, 8, 15, 16, 17, 20, 22], "cluster": [5, 6, 8, 9, 14, 16, 17, 18, 19, 20, 29], "could": 5, "16": [5, 7, 10, 11, 13, 21], "googleapi": [5, 29], "autogener": 5, "60": [5, 7], "execut": [5, 7, 8, 13, 18, 19, 20, 22, 24], "search": 5, "hardwar": 5, "rewrit": 5, "ca": [5, 9], "autom": [5, 6, 7, 13, 29], "databas": [5, 7, 22], "ma": 5, "reason": 5, "interest": 5, "customiz": 5, "download": [5, 18], "hub": [5, 22], "pullpolici": 5, "fullfil": 5, "pull": [5, 22, 25, 29], "url": 5, "compos": [5, 13], "follw": 5, "tag": [5, 8, 18, 19, 21, 22, 29], "ifnotpres": 5, "much": [5, 17], "100m": [5, 13], "128mi": 5, "request": [5, 8, 9, 13, 20, 22, 25, 26], "32mi": 5, "decid": [5, 21], "createselfsignedcertif": 5, "certificatesecretnam": 5, "overwrit": 5, "under": [5, 7, 16, 19], "cours": 5, "scyllaimag": 5, "agentimag": 5, "agent": [5, 7, 13, 22], "express": [5, 22], "5g": 5, "1gi": [5, 9, 18], "gib": [5, 22], "scyllaclust": [5, 6, 8, 9, 13, 14, 18, 19, 20, 22, 25, 29], "customzi": 5, "consist": [5, 7, 13, 18, 20], "applic": [5, 20], "mani": [5, 9, 20, 22, 25], "500m": 5, "500mi": 5, "similarli": [5, 25], "controllerimag": 5, "controllerresourc": 5, "30mi": 5, "20mi": 5, "land": [5, 20], "bootstrap": [5, 17], "isn": 5, "valid": [5, 7, 9, 19, 22, 29], "correctli": 5, "5dbcb54f5c": 5, "vjm4m": 5, "51": [5, 17], "wfjbw": 5, "clusterip": [5, 8, 17], "105": 5, "207": 5, "130": 5, "none": [5, 8, 17], "443": [5, 9], "TO": 5, "replicaset": 5, "669db64dd": 5, "bcm4v": 5, "89": 5, "844ccc56c4": 5, "drbth": 5, "rhwqx": 5, "231": [5, 17], "53": [5, 7], "80": 5, "5090": 5, "9180": [5, 8, 17], "5m58": 5, "4m29": 5, "5m59": 5, "43": [5, 8, 17], "149": 5, "92": 5, "7000": [5, 8, 17], "7001": [5, 8, 17], "7199": [5, 8, 17], "10001": [5, 8, 17], "9042": [5, 8, 17], "9142": [5, 8, 17], "9160": [5, 8, 17], "49": 5, "exactli": [5, 21], "were": 5, "ask": 5, "spin": [5, 7], "servicemonitor": 5, "observ": [5, 19], "managg": 5, "fals": [5, 7, 9, 11, 13, 18, 22], "notic": [5, 9], "prometh": 5, "abl": [5, 10, 28], "scrape": 5, "uninstal": 5, "downscal": 6, "report": [6, 26], "lesson": 6, "univers": 6, "multi": [6, 10, 11, 25], "scale": [6, 19, 25], "dead": 6, "autoh": 6, "topic": [6, 15], "begin": [6, 19], "chart": [6, 9, 21, 29], "expos": [6, 13], "experiment": [6, 9, 20, 29], "procedur": [6, 13, 17, 18, 19, 29], "releas": [6, 29], "contribut": 6, "wide": 7, "predict": 7, "With": [7, 11], "proprietari": 7, "softwar": 7, "licens": 7, "agreement": [7, 19], "spawn": 7, "mission": 7, "watch": 7, "synchron": 7, "regist": [7, 8, 18], "id": [7, 10, 13, 17, 18], "map": [7, 22], "fulli": [7, 13], "unschedul": [7, 14], "bare": [7, 9], "metal": [7, 9], "dc": [7, 13, 22], "37m": 7, "28m": 7, "7bd9f968b9": 7, "w25jw": 7, "info": [7, 25], "2020": [7, 19, 21], "09": [7, 18, 21], "23t11": 7, "25": [7, 8, 13, 21], "27": [7, 13, 21], "882z": 7, "m": [7, 22], "build_dat": 7, "commit": [7, 21], "built_bi": 7, "go_vers": 7, "loglevel": 7, "debug": [7, 25], "apiaddress": 7, "127": 7, "5080": 7, "_trace_id": 7, "lqejv3kdr5gx9m3xq2ynnq": 7, "28": 7, "435z": 7, "26": 7, "238z": 7, "20200816": 7, "76cc4dcc": 7, "pid": 7, "xqhkj0our8e6imdepm62hg": 7, "54": 7, "519z": 7, "tlscertfil": 7, "var": 7, "lib": 7, "scylla_manag": 7, "crt": [7, 9], "tlskeyfil": 7, "tlscafil": 7, "56090": 7, "prometheusscrapeinterv": 7, "5000000000": 7, "56112": 7, "logger": 7, "stderr": 7, "ssl": [7, 9], "localdc": 7, "migratedir": 7, "etc": [7, 9, 20], "migratetimeout": 7, "30000000000": 7, "migratemaxwaitschemaagr": 7, "300000000000": 7, "replicationfactor": 7, "600000000": 7, "tokenawar": 7, "certfil": 7, "usercertfil": 7, "userkeyfil": 7, "healthcheck": 7, "250000000": 7, "ssltimeout": 7, "750000000": 7, "diskspacefreeminperc": 7, "agemax": 7, "43200000000000": 7, "segmentsperrepair": 7, "shardparallelmax": 7, "shardfailedsegmentsmax": 7, "100": [7, 18, 22], "pollinterv": [7, 22], "200000000": 7, "errorbackoff": 7, "shardingignoremsbbit": 7, "config_fil": 7, "mnt": 7, "tutori": 7, "alreadi": [7, 9, 18, 19], "d1d532cd": 7, "49f2": 7, "4c97": 7, "9263": 7, "25126532803b": 7, "sctool": [7, 18], "ti": [7, 17, 18], "next": [7, 19], "400b2723": 7, "eec5": 7, "422a": 7, "b7f3": 7, "236a0e10575b": 7, "23": [7, 8], "sep": 7, "14": 7, "42": 7, "cest": 7, "15": [7, 18], "healthcheck_rest": 7, "28169610": 7, "a969": 7, "4c20": 7, "9d11": 7, "ab7568b8a1bd": 7, "29": 7, "57": 7, "1m": 7, "recur": 7, "healhcheck": 7, "frontend": 7, "altern": [7, 9, 22], "prior": 7, "interv": [7, 22], "1d": [7, 22], "weekli": [7, 22], "locat": [7, 11, 18, 22, 25], "s3": [7, 18, 22], "retent": [7, 22], "7d": [7, 22], "daili": [7, 22], "7": [7, 13, 21], "consult": 7, "bucket": [7, 22], "spot": 7, "275aae7f": 7, "c436": 7, "4fc8": 7, "bcec": 7, "479e65fb8372": 7, "58": 7, "d4946360": 7, "c29d": 7, "4bb4": 7, "8b9d": 7, "619ada495c2a": 7, "38": 7, "shortli": 7, "progress": [7, 9, 13, 18], "utc": [7, 18], "durat": [7, 18, 22, 25], "69": 7, "06": [7, 21], "system_distribut": 7, "00": 7, "system_trac": 7, "present": [7, 10], "wasn": 7, "cannot": [7, 20], "due": [7, 13, 14, 18, 22], "lack": [7, 22], "target": [7, 10, 18, 20, 29], "62": [7, 17], "attempt": 7, "correct": [7, 9], "107": [7, 13], "193": 7, "33": 7, "109": 7, "197": 7, "00000000": 7, "0000": 7, "000000000000": 7, "adhoc": 7, "retri": [7, 19, 22], "2b9dbe8c": 7, "9daa": 7, "4703": 7, "a66d": 7, "c29f63a917c8": 7, "infinit": 7, "appear": 7, "solv": [8, 29], "disambigu": [8, 29], "backward": [8, 29], "incompat": [8, 29], "involv": 8, "detach": 8, "period": 8, "noth": 8, "garbag": 8, "collect": [8, 9, 26], "shouldn": [8, 17], "caus": [8, 16, 17, 19, 20], "downtim": 8, "consid": 8, "hacki": 8, "box": 8, "stage": [8, 19], "whole": [8, 19], "question": 8, "welcom": 8, "slack": 8, "channel": [8, 10], "sequenti": 8, "30m": [8, 29], "cert": 8, "offici": [8, 22], "websit": 8, "extract": [8, 13], "customresourcedefinit": [8, 29], "previou": [8, 19], "v1alpha1": [8, 9, 20, 29], "uuid": 8, "newli": 8, "metadata": [8, 9, 10, 13, 18, 20, 22], "uid": 8, "12a3678d": 8, "8511": 8, "4c9c": 8, "8a48": 8, "fa78d3992694": 8, "somewher": 8, "grant": 8, "lookup": 8, "patch": [8, 13, 18, 19, 29], "json": [8, 13, 18], "rule": [8, 10, 28], "apigroup": 8, "verb": 8, "amend": 8, "109m": 8, "96": 8, "66": 8, "22": [8, 21], "108m": 8, "246": 8, "106m": 8, "ownerrefer": 8, "column": 8, "lower": [8, 22], "110m": 8, "107m": 8, "st": [8, 29], "104m": 8, "bound": [8, 14, 17, 20], "old": [8, 17, 29], "boot": [8, 19], "600": 8, "initi": [8, 13, 22], "initcontain": 8, "bump": 8, "endpointsselector": 9, "matchlabel": [9, 13], "ident": 9, "volumeclaimtempl": 9, "webinterfac": 9, "ingressclassnam": 9, "dnsdomain": 9, "passthrough": 9, "futur": [9, 10, 11], "third": 9, "parti": 9, "skip": [9, 25], "5m": 9, "met": [9, 13, 18], "degrad": [9, 13, 18], "revis": 9, "65b89d55bb": 9, "matter": 9, "packet": [9, 20], "tl": [9, 18], "sni": 9, "caller": 9, "properli": [9, 19, 28, 29], "real": 9, "grafana_serving_cert": 9, "index": [9, 13], "base64": [9, 13], "d": [9, 13, 22, 29], "grafana_us": 9, "admin": [9, 25], "grafana_password": 9, "appropri": 9, "often": [9, 22, 28], "wildcard": 9, "mydomain": 9, "cname": 9, "similar": [9, 10, 13, 25], "curl": 9, "dev": [9, 22], "null": 9, "w": 9, "http_code": 9, "cacert": 9, "echo": 9, "200": 9, "beyond": [9, 28], "unless": [9, 25], "ingress_port": 9, "loadbalanc": 9, "ingress_ip": 9, "slightli": [9, 22], "conveni": 9, "internal_ip": 9, "external_ip": 9, "rang": [9, 10, 11, 22], "item": 9, "eq": 9, "internalip": 9, "easili": [10, 11], "infrastructur": [10, 11, 13], "tailor": [10, 11], "simplic": [10, 11, 13], "predefin": [10, 11, 25], "throughout": [10, 11, 13], "exemplari": [10, 11], "v1alpha5": 10, "clusterconfig": 10, "availabilityzon": 10, "cidr": [10, 11], "context": [10, 11, 20, 25], "flag": [10, 11, 14, 18, 25, 29], "return": [10, 11, 16], "workload": [10, 11, 20], "volum": [10, 11, 13, 22, 25], "provision": [10, 11, 13], "non": [10, 13, 18, 19], "overlap": [10, 11], "ipv4": [10, 11], "2a": [10, 13], "2b": [10, 13], "2c": [10, 13], "172": [10, 11, 13, 17], "analog": [10, 11], "known": [10, 23], "pcx": 10, "08077dcc008fbbab6": 10, "privat": 10, "destin": 10, "given": [10, 17, 22, 25], "send": [10, 25], "preconfigur": 10, "omit": 10, "readabl": [10, 22], "publicroutet": 10, "flow": 10, "inbound": 10, "share": [10, 11, 20, 22], "correspond": [10, 11, 22], "clustersharednodesecuritygroup": 10, "td05v9evu3b8": 10, "1fr9ydlu0ve7m": 10, "guidanc": [10, 11], "googl": 11, "virtual": 11, "secondari": 11, "east1": [11, 16], "17": [11, 21], "18": [11, 13], "alia": 11, "subnetwork": 11, "permit": 11, "model": [11, 22], "hash": 11, "filter": 11, "prioriti": 11, "f17db261": 11, "1000": 11, "udp": 11, "icmp": 11, "esp": 11, "ah": 11, "sctp": 11, "0bb60902": 11, "build": [12, 13, 21], "discuss": 13, "unrel": 13, "expect": [13, 29], "meet": [13, 20], "topologi": 13, "storageclass": [13, 22], "11": [13, 18, 21], "machineri": 13, "scyladb": 13, "intervent": 13, "human": [13, 22], "notabl": 13, "leav": [13, 17, 20], "behind": 13, "mechan": 13, "externalse": 13, "binari": [13, 25], "paramet": [13, 22], "understood": 13, "contact": 13, "ring": 13, "join": [13, 17], "function": [13, 21, 28], "enhanc": 13, "propos": 13, "subset": [13, 25], "scyllaclus": 13, "headless": 13, "howev": [13, 20], "context_dc1": 13, "context_dc2": 13, "correspondingli": 13, "accordingli": 13, "across": [13, 20, 22], "center": 13, "dc1": [13, 22], "automaticorphanednodecleanup": [13, 14, 22], "storageclassnam": [13, 22], "1800g": 13, "agentresourc": [13, 20, 22], "250m": 13, "56g": 13, "placement": [13, 20, 22], "podantiaffin": [13, 22], "requiredduringschedulingignoredduringexecut": [13, 22], "topologykei": 13, "labelselector": 13, "nodeaffin": [13, 22], "nodeselectorterm": [13, 22], "matchexpress": [13, 22], "effect": [13, 22], "un": [13, 17], "nodetool": [13, 17], "normal": [13, 17], "move": [13, 17, 19, 20], "token": [13, 17, 22, 25], "70": 13, "195": 13, "290": 13, "kb": [13, 17], "256": [13, 17], "494277b9": 13, "121c": 13, "4af9": 13, "bd63": 13, "3d0a7b9305f7": 13, "59": 13, "24": [13, 18], "559": 13, "a3a98e08": 13, "0dfd": 13, "4a25": 13, "a96a": 13, "c5ab2f47eb37": 13, "19": [13, 21], "237": 13, "64b6292a": 13, "327f": 13, "4128": 13, "852a": 13, "6004039f402e": 13, "ephemer": 13, "natur": 13, "ill": 13, "advis": [13, 25, 28], "high": 13, "likelihood": 13, "undesir": 13, "startup": 13, "fallback": 13, "peer": 13, "unreach": 13, "domain": [13, 22], "sheer": 13, "util": 13, "dc2": 13, "705": 13, "764": 13, "634": 13, "39": 13, "209": 13, "336": 13, "7c30ea55": 13, "7a4f": 13, "4d93": 13, "86f7": 13, "c881772ebe62": 13, "759": 13, "665dde7e": 13, "e420": 13, "4db3": 13, "8c54": 13, "ca71efd39b2": 13, "87": 13, "503": 13, "c19c89cb": 13, "e24c": 13, "4062": 13, "9df4": 13, "2aa90ab29a99": 13, "cr": 13, "random": 13, "auth": 13, "auth_token": 13, "84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf": 13, "stringdata": 13, "forceredeploymentreason": [13, 18], "sync": [13, 17], "incid": 14, "explicit": 14, "becom": [14, 19, 21], "pvc": 14, "affin": 14, "hi": 14, "cleanup": [15, 19, 22], "lost": 15, "mainten": [15, 19], "restor": [15, 19, 29], "probe": [16, 29], "failur": [16, 17, 19, 22], "live": 16, "succe": 16, "registri": 16, "stai": 16, "aliv": 16, "turn": [16, 19, 29], "bring": [16, 17, 19, 29], "front": 16, "possibl": [17, 22], "stream": 17, "bandwidth": 17, "125": 17, "110": 17, "74": 17, "63": 17, "8ebd6114": 17, "969c": 17, "44af": 17, "a978": 17, "87a4a6c65c3": 17, "189": 17, "91": 17, "03": [17, 21], "35d0cb19": 17, "35ef": 17, "482b": 17, "92a4": 17, "b63eee4527e5": 17, "77": 17, "1ffa7a82": 17, "c41c": 17, "4706": 17, "8f5f": 17, "4d45a39c7003": 17, "identifi": [17, 18], "3h12m": 17, "3h11m": 17, "3h5m": 17, "drain": [17, 19], "b4b390a1": 17, "6j12": 17, "ignor": 17, "daemonset": [17, 20], "pend": 17, "3h21m": 17, "3h19m": 17, "8m14": 17, "recreat": [17, 29], "3h27m": 17, "3h25m": 17, "9": [17, 18, 19, 21, 29], "store": [17, 18, 22], "visibl": 17, "191": 17, "fresh": [18, 29], "gate": 18, "automatictlscertif": 18, "arg": 18, "foo": 18, "af1dd5cd": 18, "0406": 18, "4974": 18, "949f": 18, "dc9842980080": 18, "ebd82268": 18, "efb7": 18, "407e": 18, "a540": 18, "3619ae053778": 18, "snapshot": [18, 19, 22], "cluster_id": 18, "backup_loc": 18, "ff36d7e0": 18, "af2": 18, "458c": 18, "afe6": 18, "868e0f3396b2": 18, "sm_20240105115931utc": 18, "409mib": 18, "system_schema": [18, 19], "tabl": [18, 21, 22], "schema": [18, 19], "snapshot_tag": 18, "57228c52": 18, "7cf6": 18, "4271": 18, "8c8d": 18, "d446ff160747": 18, "0dd20cdf": 18, "abc4": 18, "11ee": 18, "951c": 18, "6e7993cf42": 18, "05": [18, 21], "jan": 18, "02": [18, 21], "success": 18, "214": 18, "150k": 18, "suggest": 18, "63642069": 18, "bed5": 18, "4def": 18, "ba0f": 18, "68c49e47ace1": 18, "ab015cef": 18, "abc8": 18, "9521": 18, "48": 18, "04": [18, 21], "post": 18, "intens": [18, 22], "parallel": [18, 19, 22], "detect": 19, "semant": 19, "nightli": 19, "so_data_20201228135002utc": 19, "validate_upgrad": 19, "so_system_20201228135002utc": 19, "underli": [19, 22], "ondelet": 19, "upgradestrategi": 19, "trace": 19, "displai": 19, "begin_upgrad": 19, "check_schema_agr": 19, "minut": 19, "create_system_backup": 19, "find_next_rack": 19, "decis": 19, "upgrade_image_in_pod_spec": 19, "find_next_nod": 19, "enable_maintenance_mod": 19, "drain_nod": 19, "backup_data": 19, "disable_maintenance_mod": 19, "delete_pod": 19, "clear_data_backup": 19, "clear_system_backup": 19, "restore_upgrade_strategi": 19, "finish_upgrad": 19, "recov": 19, "stuck": 19, "refus": 19, "replica": [19, 22], "root": 19, "sstabl": 19, "left": [19, 22], "suppos": 20, "perftun": 20, "optmiz": 20, "kernel": 20, "spread": 20, "irq": 20, "immedi": 20, "effic": 20, "pin": [20, 22, 29], "interrupt": 20, "One": 20, "switch": 20, "coupl": 20, "daemon": 20, "space": 20, "advantag": 20, "special": 20, "qo": 20, "doubl": 20, "cf": 20, "quota": 20, "enforc": 20, "around": 20, "distribut": 20, "part": [20, 22], "fulfil": 20, "receiv": 20, "500gi": 20, "1g": 20, "16g": 20, "aim": 21, "ship": 21, "approxim": 21, "week": 21, "advisori": 21, "hit": [21, 25], "code": [21, 29], "freez": 21, "everyon": 21, "08": 21, "07": 21, "01": 21, "2022": 21, "2021": 21, "21": 21, "elig": 21, "situat": 21, "assess": 21, "action": 21, "branch": [21, 29], "trigger": 21, "publish": 21, "artifact": 21, "e2": 21, "suit": [21, 28], "vx": 21, "y": 21, "x": 21, "rc": 21, "ga": 21, "aren": 21, "scratch": [21, 29], "rather": 21, "candid": 21, "qualiti": 21, "qa": 21, "sing": 21, "sha": 21, "Be": 21, "cri": 21, "v1alpha2": 21, "ratelimit": 22, "500g": 22, "32gi": 22, "unset": 22, "agentrepositori": 22, "orphan": 22, "genericupgrad": 22, "failurestrategi": 22, "poll": 22, "sent": 22, "kube": [22, 25], "apiserv": [22, 28], "affect": [22, 25], "overal": 22, "spent": 22, "scyllaarg": 22, "dnspolici": 22, "moment": 22, "schedul": 22, "startdat": 22, "rfc3339": 22, "3d2h10m": 22, "numretri": 22, "glob": 22, "otherdc": 22, "exclud": 22, "failfast": 22, "stop": 22, "shard": 22, "max_repair_ranges_in_parallel": 22, "integ": 22, "higher": 22, "faster": 22, "impact": 22, "granular": 22, "resum": 22, "row": 22, "decim": 22, "percent": 22, "string": 22, "float": 22, "runtim": [22, 25], "rf": 22, "formula": 22, "calcul": 22, "table_prefix_": 22, "smalltablethreshold": 22, "threshold": 22, "mib": 22, "tib": 22, "1gib": 22, "alphanumer": 22, "dot": 22, "charact": 22, "forbidden": 22, "gc": 22, "megabyt": 22, "snapshotparallel": 22, "global": 22, "uploadparallel": 22, "confus": 22, "ram": 22, "minimum": 22, "amount": 22, "volumemount": 22, "agentvolumemount": 22, "scyllaconfig": 22, "scyllaagentconfig": 22, "subfield": 22, "podaffin": 22, "overview": 23, "troubleshoot": 23, "gather": 23, "8th": 24, "migrat": [24, 29], "008_": 24, "hairpin": 24, "sudo": 24, "docker0": 24, "promisc": 24, "embed": [25, 26], "goe": 25, "wrong": 25, "censor": 25, "sensit": 25, "That": 25, "said": 25, "review": 25, "archiv": [25, 26], "suppli": 25, "kubeconfig": 25, "There": [25, 28, 29], "slight": 25, "deviat": 25, "selinux": 25, "mention": 25, "lsetxattr": 25, "try": 25, "plugin": 25, "view": 25, "minifi": 25, "user_nam": 25, "few": 25, "serviceaccount": 25, "must_gather_token": 25, "1h": 25, "mktemp": [25, 29], "yq": 25, "mikefarah": 25, "rm": 25, "ro": 25, "pwd": 25, "workspac": 25, "workdir": 25, "namespace_with_broken_scyllaclust": 25, "still": 25, "wouldn": 25, "enough": 25, "administr": 26, "paid": 26, "aris": 26, "visit": 26, "unfortun": 28, "sdn": 28, "plane": [28, 29], "firewal": 28, "conform": 28, "break": 28, "workaround": 28, "reconfigur": 28, "5871": 29, "7735": 29, "release_nam": 29, "tmpdir": 29, "untar": 29, "untardir": 29, "printf": 29, "xarg": 29, "minor": 29, "symlink": 29, "brought": 29, "lot": 29, "mutatingwebhookconfigur": 29, "mutat": 29, "validatingwebhookconfigur": 29, "95m": 29, "livenessprob": 29, "httpget": 29, "healthz": 29, "8080": 29, "readinessprob": 29, "retainkei": 29, "readyz": 29, "cat": 29, "preserv": 29}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"contribut": 0, "scylla": [0, 1, 3, 4, 5, 6, 7, 13, 15, 17, 19, 22, 24, 29], "oper": [0, 1, 3, 4, 5, 6, 9, 10, 11, 15, 29], "prerequisit": [0, 1, 3, 4, 5, 7, 9, 10, 11, 13, 25], "initi": [0, 3], "setup": [0, 1, 4], "creat": [0, 1, 3, 4, 10, 11], "fork": 0, "clone": 0, "your": [0, 26], "add": 0, "upstream": 0, "remot": 0, "develop": 0, "build": [0, 10, 11], "project": 0, "branch": 0, "updat": [0, 10], "submit": 0, "pull": 0, "request": 0, "commit": 0, "histori": 0, "messag": 0, "deploi": [1, 3, 4, 5, 7, 9, 10, 11, 12, 13], "ek": [1, 10, 28], "tl": [1, 4, 5], "dr": [1, 4, 5], "walkthrough": [1, 4], "configur": [1, 3, 4, 10, 11], "environ": [1, 4], "variabl": [1, 4], "an": [1, 9], "cluster": [1, 2, 3, 4, 7, 10, 11, 12, 13, 22, 25, 26, 28], "instal": [1, 5, 28], "script": 1, "third": 1, "parti": 1, "depend": 1, "scylladb": [1, 4, 10, 11, 12, 13], "set": [1, 3, 4, 22], "up": [1, 3, 4, 7, 24], "node": [1, 2, 4, 10, 11, 13, 14, 15, 17, 20], "local": [1, 3, 4], "volum": [1, 4], "provision": [1, 4], "access": [1, 3, 4, 9], "databas": [1, 3, 4], "delet": [1, 4], "expos": 2, "scyllaclust": [2, 3], "option": 2, "servic": 2, "templat": 2, "headless": 2, "type": 2, "clusterip": 2, "loadbalanc": 2, "broadcast": 2, "podip": [2, 13], "serviceclusterip": 2, "serviceloadbalanceringress": 2, "deploy": 2, "exampl": 2, "In": 2, "onli": 2, "vpc": [2, 10, 11], "client": 2, "multi": [2, 12, 13], "internet": 2, "kubernet": [3, 4, 7, 10, 11, 12, 13, 20], "run": [3, 10, 11, 25], "download": 3, "cert": [3, 5], "manag": [3, 5, 7, 9, 13, 22, 24], "host": 3, "network": [3, 10, 11, 13], "contain": 3, "kernel": 3, "paramet": 3, "altern": 3, "agent": 3, "auth": 3, "token": 3, "monitor": [3, 5, 9], "scale": 3, "benchmark": 3, "cassandra": 3, "stress": 3, "clean": [3, 7], "troubleshoot": [3, 7, 26, 27, 28], "gke": [4, 11, 28], "googl": 4, "engin": 4, "yourself": 4, "admin": 4, "stack": 5, "us": [5, 9, 13, 15], "helm": [5, 29], "chart": 5, "repositori": 5, "imag": 5, "resourc": [5, 25], "webhook": [5, 28], "custom": [5, 28], "control": 5, "result": 5, "cleanup": [5, 14], "document": 6, "architectur": 7, "registr": 7, "task": 7, "schedul": [7, 21], "version": [8, 19], "migrat": 8, "v0": [8, 29], "3": [8, 29], "0": [8, 29], "v1": [8, 29], "procedur": 8, "requir": 9, "prometheu": 9, "wait": 9, "roll": 9, "out": 9, "haproxi": 9, "ingress": 9, "scylladbmonitor": [9, 13], "grafana": 9, "connect": 9, "through": 9, "resolv": 9, "domain": 9, "unresolv": 9, "variant": 9, "externalip": 9, "nodeport": 9, "multipl": [10, 11, 13], "amazon": 10, "inter": [10, 11], "first": [10, 11, 13], "prepar": [10, 11], "second": [10, 11, 13], "peer": 10, "rout": 10, "tabl": 10, "secur": 10, "group": 10, "subnet": 11, "firewal": 11, "rule": 11, "datacent": [12, 13, 22], "interconnect": 13, "extern": 13, "seed": 13, "context": 13, "retriev": 13, "automat": 14, "replac": [14, 17], "case": 14, "when": 14, "k8": 14, "i": 14, "lost": 14, "mainten": 16, "mode": 16, "dead": 17, "restor": 18, "from": 18, "backup": 18, "upgrad": [19, 29], "perform": 20, "tune": 20, "releas": 21, "support": [21, 23, 26], "backport": 21, "polici": 21, "ci": 21, "cd": 21, "autom": 21, "promot": 21, "gener": 21, "avail": 21, "matrix": 21, "crd": 22, "sampl": 22, "explan": 22, "rack": 22, "known": 24, "issu": [24, 26, 28], "doe": 24, "boot": 24, "minikub": 24, "truncat": 24, "queri": 24, "work": 24, "gather": [25, 26], "data": [25, 26], "must": 25, "podman": 25, "docker": 25, "limit": 25, "particular": 25, "namespac": 25, "collect": 25, "everi": 25, "overview": 26, "get": 26, "about": 26, "cni": 28, "privat": 28, "via": 29, "kubectl": 29, "2": 29, "1": 29}, "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": {"Node operations using Scylla Operator": [[15, "node-operations-using-scylla-operator"]], "Replacing a Scylla node": [[17, "replacing-a-scylla-node"]], "Replacing a dead node": [[17, "replacing-a-dead-node"]], "Maintenance mode": [[16, "maintenance-mode"]], "Automatic cleanup and replacement in case when k8s node is lost": [[14, "automatic-cleanup-and-replacement-in-case-when-k8s-node-is-lost"]], "Upgrading version of Scylla": [[19, "upgrading-version-of-scylla"]], "Restore from backup": [[18, "restore-from-backup"]], "Performance tuning": [[20, "performance-tuning"]], "Node tuning": [[20, "node-tuning"]], "Kubernetes tuning": [[20, "kubernetes-tuning"]], "Known issues": [[24, "known-issues"]], "Scylla Manager does not boot up on Minikube": [[24, "scylla-manager-does-not-boot-up-on-minikube"]], "TRUNCATE queries does not work on Minikube": [[24, "truncate-queries-does-not-work-on-minikube"]], "Support overview": [[26, "support-overview"]], "Get support": [[26, "get-support"]], "Troubleshooting issues": [[26, "troubleshooting-issues"]], "Gather data about your cluster": [[26, "gather-data-about-your-cluster"]], "Support": [[23, "support"]], "Troubleshooting": [[27, "troubleshooting"], [7, "troubleshooting"], [3, "troubleshooting"]], "Releases": [[21, "releases"]], "Schedule": [[21, "schedule"]], "Supported releases": [[21, "supported-releases"]], "Backport policy": [[21, "backport-policy"]], "CI/CD": [[21, "ci-cd"]], "Automated promotions": [[21, "automated-promotions"]], "Generally available": [[21, "generally-available"]], "Support matrix": [[21, "support-matrix"]], "Scylla Cluster CRD": [[22, "scylla-cluster-crd"]], "Sample": [[22, "sample"]], "Settings Explanation": [[22, "settings-explanation"]], "Cluster Settings": [[22, "cluster-settings"]], "Scylla Manager settings": [[22, "scylla-manager-settings"]], "Datacenter Settings": [[22, "datacenter-settings"]], "Rack Settings": [[22, "rack-settings"]], "Gathering data with must-gather": [[25, "gathering-data-with-must-gather"]], "Running must-gather": [[25, "running-must-gather"]], "Prerequisites": [[25, "prerequisites"], [9, "prerequisites"], [11, "prerequisites"], [13, "prerequisites"], [7, "prerequisites"], [10, "prerequisites"], [0, "prerequisites"], [5, "prerequisites"], [4, "prerequisites"], [1, "prerequisites"], [3, "prerequisites"]], "Podman": [[25, "podman"]], "Docker": [[25, "docker"]], "Limiting must-gather to a particular namespace": [[25, "limiting-must-gather-to-a-particular-namespace"]], "Collecting every resource in the cluster": [[25, "collecting-every-resource-in-the-cluster"]], "Monitoring": [[9, "monitoring"], [5, "monitoring"]], "Deploy managed monitoring": [[9, "deploy-managed-monitoring"]], "Requirements": [[9, "requirements"]], "Deploy Prometheus Operator": [[9, "deploy-prometheus-operator"]], "Wait for Prometheus Operator to roll out": [[9, "wait-for-prometheus-operator-to-roll-out"]], "Deploy HAProxy Ingress": [[9, "deploy-haproxy-ingress"]], "Wait for HAProxy Ingress to roll out": [[9, "wait-for-haproxy-ingress-to-roll-out"]], "Deploy ScyllaDBMonitoring": [[9, "deploy-scylladbmonitoring"]], "Wait for ScyllaDBMonitoring to roll out": [[9, "wait-for-scylladbmonitoring-to-roll-out"]], "Wait for Prometheus to roll out": [[9, "wait-for-prometheus-to-roll-out"]], "Wait for Grafana to roll out": [[9, "wait-for-grafana-to-roll-out"]], "Accessing Grafana": [[9, "accessing-grafana"]], "Connecting through Ingress using a resolvable domain": [[9, "connecting-through-ingress-using-a-resolvable-domain"]], "Connecting through Ingress using an unresolvable domain": [[9, "connecting-through-ingress-using-an-unresolvable-domain"]], "Variants": [[9, "variants"]], "Ingress ExternalIP": [[9, "ingress-externalip"]], "Ingress NodePort": [[9, "ingress-nodeport"]], "Connection": [[9, "connection"]], "Deploying multi-datacenter ScyllaDB clusters in Kubernetes": [[12, "deploying-multi-datacenter-scylladb-clusters-in-kubernetes"]], "Version migrations": [[8, "version-migrations"]], "v0.3.0 -> v1.0.0 migration": [[8, "v0-3-0-v1-0-0-migration"]], "Procedure": [[8, "procedure"]], "Build multiple GKE clusters with inter-Kubernetes networking": [[11, "build-multiple-gke-clusters-with-inter-kubernetes-networking"]], "Create and configure a VPC network": [[11, "create-and-configure-a-vpc-network"]], "Create the VPC network": [[11, "create-the-vpc-network"]], "Create VPC network subnets": [[11, "create-vpc-network-subnets"]], "Create GKE clusters": [[11, "create-gke-clusters"]], "Create the first GKE cluster": [[11, "create-the-first-gke-cluster"]], "Deploy ScyllaDB Operator": [[11, "deploy-scylladb-operator"], [10, "deploy-scylladb-operator"]], "Prepare nodes for running ScyllaDB": [[11, "prepare-nodes-for-running-scylladb"], [10, "prepare-nodes-for-running-scylladb"]], "Create the second GKE cluster": [[11, "create-the-second-gke-cluster"]], "Configure the firewall rules": [[11, "configure-the-firewall-rules"]], "Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters": [[13, "deploy-a-multi-datacenter-scylladb-cluster-in-multiple-interconnected-kubernetes-clusters"]], "Multi Datacenter ScyllaDB Cluster": [[13, "multi-datacenter-scylladb-cluster"]], "External seeds": [[13, "external-seeds"]], "Networking": [[13, "networking"]], "Deploy a multi-datacenter ScyllaDB Cluster": [[13, "deploy-a-multi-datacenter-scylladb-cluster"]], "Using context": [[13, "using-context"]], "Deploy the first datacenter": [[13, "deploy-the-first-datacenter"]], "Retrieve PodIPs of ScyllaDB nodes for use as external seeds": [[13, "retrieve-podips-of-scylladb-nodes-for-use-as-external-seeds"]], "Deploy the second datacenter": [[13, "deploy-the-second-datacenter"]], "Scylla Manager": [[13, "scylla-manager"], [5, "scylla-manager"]], "ScyllaDBMonitoring": [[13, "scylladbmonitoring"]], "Deploying Scylla Manager on a Kubernetes Cluster": [[7, "deploying-scylla-manager-on-a-kubernetes-cluster"]], "Architecture": [[7, "architecture"]], "Deploy Scylla Manager": [[7, "deploy-scylla-manager"]], "Cluster registration": [[7, "cluster-registration"]], "Task scheduling": [[7, "task-scheduling"]], "Clean Up": [[7, "clean-up"], [3, "clean-up"]], "Build multiple Amazon EKS clusters with inter-Kubernetes networking": [[10, "build-multiple-amazon-eks-clusters-with-inter-kubernetes-networking"]], "Create EKS clusters": [[10, "create-eks-clusters"]], "Create the first EKS cluster": [[10, "create-the-first-eks-cluster"]], "Create the second EKS cluster": [[10, "create-the-second-eks-cluster"]], "Configure the network": [[10, "configure-the-network"]], "Create VPC peering": [[10, "create-vpc-peering"]], "Update route tables": [[10, "update-route-tables"]], "Update security groups": [[10, "update-security-groups"]], "Contributing to Scylla Operator": [[0, "contributing-to-scylla-operator"]], "Initial Setup": [[0, "initial-setup"]], "Create a Fork": [[0, "create-a-fork"]], "Clone Your Fork": [[0, "clone-your-fork"]], "Add Upstream Remote": [[0, "add-upstream-remote"]], "Development": [[0, "development"]], "Building the project": [[0, "building-the-project"]], "Create a Branch": [[0, "create-a-branch"]], "Updating Your Fork": [[0, "updating-your-fork"]], "Submitting a Pull Request": [[0, "submitting-a-pull-request"]], "Commit History": [[0, "commit-history"]], "Commit messages": [[0, "commit-messages"]], "Submitting": [[0, "submitting"]], "Exposing ScyllaCluster": [[2, "exposing-scyllacluster"]], "Expose Options": [[2, "expose-options"]], "Node Service Template": [[2, "node-service-template"]], "Headless Type": [[2, "headless-type"]], "ClusterIP Type": [[2, "clusterip-type"]], "LoadBalancer Type": [[2, "loadbalancer-type"]], "Broadcast Options": [[2, "broadcast-options"]], "PodIP Type": [[2, "podip-type"]], "ServiceClusterIP Type": [[2, "serviceclusterip-type"]], "ServiceLoadBalancerIngress Type": [[2, "serviceloadbalanceringress-type"]], "Deployment Examples": [[2, "deployment-examples"]], "In-cluster only": [[2, "in-cluster-only"]], "In-cluster node-to-node, VPC clients-to-nodes": [[2, "in-cluster-node-to-node-vpc-clients-to-nodes"]], "Multi VPC": [[2, "multi-vpc"]], "Internet": [[2, "internet"]], "Deploying Scylla stack using Helm Charts": [[5, "deploying-scylla-stack-using-helm-charts"]], "TL;DR": [[5, "tl-dr"]], "Deploy Cert Manager": [[5, "deploy-cert-manager"], [3, "deploy-cert-manager"]], "Helm Chart repository": [[5, "helm-chart-repository"]], "Scylla Operator Chart": [[5, "scylla-operator-chart"]], "image": [[5, "image"]], "resources": [[5, "resources"]], "webhook": [[5, "webhook"]], "Customization": [[5, "customization"], [5, "id1"], [5, "id3"]], "Installation": [[5, "installation"], [5, "id2"], [5, "id4"]], "Scylla Helm Chart": [[5, "scylla-helm-chart"]], "Scylla Manager Helm Chart": [[5, "scylla-manager-helm-chart"]], "Scylla Manager Controller": [[5, "scylla-manager-controller"]], "Scylla": [[5, "scylla"]], "Results": [[5, "results"]], "Cleanup": [[5, "cleanup"]], "Deploying Scylla on GKE": [[4, "deploying-scylla-on-gke"]], "TL;DR;": [[4, "tl-dr"], [1, "tl-dr"]], "Walkthrough": [[4, "walkthrough"], [1, "walkthrough"]], "Google Kubernetes Engine Setup": [[4, "google-kubernetes-engine-setup"]], "Configure environment variables": [[4, "configure-environment-variables"], [1, "configure-environment-variables"]], "Creating a GKE cluster": [[4, "creating-a-gke-cluster"]], "Setting Yourself as cluster-admin": [[4, "setting-yourself-as-cluster-admin"]], "Deploying ScyllaDB Operator": [[4, "deploying-scylladb-operator"], [1, "deploying-scylladb-operator"]], "Setting up nodes for ScyllaDB": [[4, "setting-up-nodes-for-scylladb"], [1, "setting-up-nodes-for-scylladb"]], "Deploying Local Volume Provisioner": [[4, "deploying-local-volume-provisioner"], [1, "deploying-local-volume-provisioner"]], "Deploy Scylla cluster": [[4, "deploy-scylla-cluster"]], "Deploying ScyllaDB": [[4, "deploying-scylladb"], [1, "deploying-scylladb"]], "Accessing the database": [[4, "accessing-the-database"], [1, "accessing-the-database"]], "Deleting a GKE cluster": [[4, "deleting-a-gke-cluster"]], "Scylla Operator Documentation": [[6, "scylla-operator-documentation"]], "Deploying Scylla on EKS": [[1, "deploying-scylla-on-eks"]], "EKS Setup": [[1, "eks-setup"]], "Creating an EKS cluster": [[1, "creating-an-eks-cluster"]], "Installing script third party dependencies": [[1, "installing-script-third-party-dependencies"]], "Deleting an EKS cluster": [[1, "deleting-an-eks-cluster"]], "Deploying Scylla on a Kubernetes Cluster": [[3, "deploying-scylla-on-a-kubernetes-cluster"]], "Running locally": [[3, "running-locally"]], "Download Scylla Operator": [[3, "download-scylla-operator"]], "Deploy Scylla Operator": [[3, "deploy-scylla-operator"]], "Create and Initialize a Scylla Cluster": [[3, "create-and-initialize-a-scylla-cluster"]], "Configure host networking": [[3, "configure-host-networking"]], "Configure container kernel parameters": [[3, "configure-container-kernel-parameters"]], "Deploying Alternator": [[3, "deploying-alternator"]], "Accessing the Database": [[3, "accessing-the-database"]], "Configure Scylla": [[3, "configure-scylla"]], "Configure Scylla Manager Agent": [[3, "configure-scylla-manager-agent"]], "Scylla Manager Agent auth token": [[3, "scylla-manager-agent-auth-token"]], "Set up monitoring": [[3, "set-up-monitoring"]], "Scale a ScyllaCluster": [[3, "scale-a-scyllacluster"]], "Benchmark with cassandra-stress": [[3, "benchmark-with-cassandra-stress"]], "Upgrade of Scylla Operator": [[29, "upgrade-of-scylla-operator"]], "Upgrade via Helm": [[29, "upgrade-via-helm"]], "Upgrade via kubectl": [[29, "upgrade-via-kubectl"]], "v1.2.0 -> v1.3.0": [[29, "v1-2-0-v1-3-0"]], "v1.1.0 -> v1.2.0": [[29, "v1-1-0-v1-2-0"]], "v1.0.0 -> v1.1.0": [[29, "v1-0-0-v1-1-0"]], "v0.3.0 -> v1.0.0": [[29, "v0-3-0-v1-0-0"]], "Troubleshooting installation issues": [[28, "troubleshooting-installation-issues"]], "Webhooks": [[28, "webhooks"]], "EKS": [[28, "eks"]], "Custom CNI": [[28, "custom-cni"]], "GKE": [[28, "gke"]], "Private clusters": [[28, "private-clusters"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/stable/sitemap.xml b/stable/sitemap.xml new file mode 100644 index 00000000000..b28dec8e6a5 --- /dev/null +++ b/stable/sitemap.xml @@ -0,0 +1,2 @@ + +https://operator.docs.scylladb.com/stable/contributing.htmlhttps://operator.docs.scylladb.com/stable/eks.htmlhttps://operator.docs.scylladb.com/stable/exposing.htmlhttps://operator.docs.scylladb.com/stable/generic.htmlhttps://operator.docs.scylladb.com/stable/gke.htmlhttps://operator.docs.scylladb.com/stable/multidc/eks.htmlhttps://operator.docs.scylladb.com/stable/helm.htmlhttps://operator.docs.scylladb.com/stable/index.htmlhttps://operator.docs.scylladb.com/stable/multidc/gke.htmlhttps://operator.docs.scylladb.com/stable/multidc/index.htmlhttps://operator.docs.scylladb.com/stable/manager.htmlhttps://operator.docs.scylladb.com/stable/multidc/multidc.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/automatic-cleanup.htmlhttps://operator.docs.scylladb.com/stable/migration.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/scylla-upgrade.htmlhttps://operator.docs.scylladb.com/stable/monitoring.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/index.htmlhttps://operator.docs.scylladb.com/stable/performance.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/maintenance-mode.htmlhttps://operator.docs.scylladb.com/stable/support/troubleshooting/installation.htmlhttps://operator.docs.scylladb.com/stable/releases.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/replace-node.htmlhttps://operator.docs.scylladb.com/stable/upgrade.htmlhttps://operator.docs.scylladb.com/stable/scylla-cluster-crd.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/restore.htmlhttps://operator.docs.scylladb.com/stable/support/index.htmlhttps://operator.docs.scylladb.com/stable/support/known-issues.htmlhttps://operator.docs.scylladb.com/stable/support/must-gather.htmlhttps://operator.docs.scylladb.com/stable/support/overview.htmlhttps://operator.docs.scylladb.com/stable/support/troubleshooting/index.htmlhttps://operator.docs.scylladb.com/stable/genindex.htmlhttps://operator.docs.scylladb.com/stable/404.htmlhttps://operator.docs.scylladb.com/stable/search.html \ No newline at end of file diff --git a/stable/support/index.html b/stable/support/index.html new file mode 100644 index 00000000000..5d341920d3b --- /dev/null +++ b/stable/support/index.html @@ -0,0 +1,575 @@ + + + + + + + + + + + + + Support | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Support

        + +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/support/known-issues.html b/stable/support/known-issues.html new file mode 100644 index 00000000000..674b2eb47c4 --- /dev/null +++ b/stable/support/known-issues.html @@ -0,0 +1,598 @@ + + + + + + + + + + + + + Known issues | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Known issues

        +
        +

        Scylla Manager does not boot up on Minikube

        +

        If your Scylla Manager is failing to apply 8th migration (008_*), then apply fix for TRUNCATE queries.

        +
        +
        +

        TRUNCATE queries does not work on Minikube

        +

        The TRUNCATE queries requires hairpinning to be enabled. On minikube this is disabled by default.

        +

        To fix it execute the following command:

        +
        minikube ssh sudo ip link set docker0 promisc on
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/support/must-gather.html b/stable/support/must-gather.html new file mode 100644 index 00000000000..e80899a8542 --- /dev/null +++ b/stable/support/must-gather.html @@ -0,0 +1,685 @@ + + + + + + + + + + + + + Gathering data with must-gather | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Gathering data with must-gather

        +

        must-gather is an embedded tool in Scylla Operator that helps collecting all the necessary info when something goes wrong.

        +

        The tool talks to the Kubernetes API, retrieves a predefined set of resources and saves them into a folder in your current directory. +By default, all collected Secrets are censored to avoid sending sensitive data. +That said, you can always review the archive before you attach it to an issue or your support request.

        +

        Given it needs to talk to the Kubernetes API, at the very least, you need to supply the --kubeconfig flag with a path to the kubeconfig file for your Kubernetes cluster, or set the KUBECONFIG environment variable.

        +
        +

        Running must-gather

        +

        There is more than one way to run must-gather. +Here are some examples of how you can run the tool.

        +
        +

        Prerequisites

        +

        All examples assume you have exported KUBECONFIG environment variable that points to a kubeconfig file on your machine. +If not, you can run this command to export the common default location. +Please make sure such a file exists.

        +
        export KUBECONFIG=~/.kube/config
        +ls -l "${KUBECONFIG}"
        +
        +
        +
        +

        Note

        +

        There can be slight deviations in the arguments for your container tool, depending on the container runtime, whether you use SELinux or similar factors.

        +

        As an example, the need for the Z option on volume mounts depends on whether you use SELinux and what context is applied on your file or directory. +If you get an error mentioning Error: lsetxattr <path>: operation not supported, try it without the Z option.

        +
        +

        Let’s also check whether your kubeconfig uses external authentication plugin. +You can determine that by running

        +
        kubectl config view --minify
        +
        +
        +

        and checking whether it uses an external exec plugin by looking for this pattern (containing the exec key)

        +
        users:
        +- name: <user_name>
        +  user:
        +    exec:
        +
        +
        +

        If not, you can skip the rest of this section.

        +

        In case your kubeconfig depends on external binaries, you have to take a few extra steps because the external binary won’t be available within our container to authenticate the requests.

        +

        Similarly to how Pods are run within Kubernetes, we’ll create a dedicated ServiceAccount for must-gather and use it to run the tool. +(When you are done using it, feel free to remove the Kubernetes resources created for that purpose.)

        +
        kubectl create namespace must-gather
        +kubectl -n must-gather create serviceaccount must-gather
        +kubectl create clusterrolebinding must-gather --clusterrole=cluster-admin --serviceaccount=must-gather:must-gather
        +export MUST_GATHER_TOKEN
        +MUST_GATHER_TOKEN=$( kubectl -n must-gather create token must-gather --duration=1h )
        +kubeconfig=$( mktemp )
        +# Create a copy of the existing kubeconfig and
        +# replace user authentication using yq, or by adjusting the fields manually.
        +kubectl config view --minify --raw -o yaml | yq -e '.users[0].user = {"token": env(MUST_GATHER_TOKEN)}' > "${kubeconfig}"
        +KUBECONFIG="${kubeconfig}"
        +
        +
        +
        +

        Note

        +

        If you don’t have yq installed, you can get it at https://github.com/mikefarah/yq/#install or you can replace the user authentication settings manually.

        +
        +
        +
        +

        Podman

        +
        podman run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro,Z" -v="$( pwd ):/workspace:Z" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig
        +
        +
        +
        +
        +

        Docker

        +
        docker run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro" -v="$( pwd ):/workspace" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig
        +
        +
        +
        +
        +
        +

        Limiting must-gather to a particular namespace

        +

        If you are running a large Kubernetes cluster with many ScyllaClusters, it may be useful to limit the collection of ScyllaClusters to a particular namespace. +Unless you hit scale issues, we advise not to use this mode, as sometimes the ScyllaClusters affect other collected resources, like the manager or they form a multi-datacenter.

        +
        scylla-operator must-gather --namespace="<namespace_with_broken_scyllacluster>"
        +
        +
        +
        +

        Note

        +

        The --namespace flag affects only ScyllaClusters. +Other resources related to the operator installation or cluster state will still be collected from other namespaces.

        +
        +
        +

        Collecting every resource in the cluster

        +

        By default, must-gather collects only a predefined subset of resources. +You can also request collecting every resource in the Kubernetes API, if the default set wouldn’t be enough to debug an issue.

        +
        scylla-operator must-gather --all-resources
        +
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/support/overview.html b/stable/support/overview.html new file mode 100644 index 00000000000..38a7883cfa0 --- /dev/null +++ b/stable/support/overview.html @@ -0,0 +1,600 @@ + + + + + + + + + + + + + Support overview | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Support overview

        +
        +

        Get support

        +

        ScyllaDB provides administrators with paid support, including Scylla Operator.

        +
        +
        +

        Troubleshooting issues

        +

        To learn more about what to do when issues arise, visit our dedicated troubleshooting section.

        +
        +
        +

        Gather data about your cluster

        +

        Scylla Operator contains an embedded tool called must-gather that can collect the required information for requesting support or reporting issues. +Support requests and bug reports are required to attach the must-gather archive to help us understand the issue.

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/support/troubleshooting/index.html b/stable/support/troubleshooting/index.html new file mode 100644 index 00000000000..1265d2eb814 --- /dev/null +++ b/stable/support/troubleshooting/index.html @@ -0,0 +1,581 @@ + + + + + + + + + + + + + Troubleshooting | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Troubleshooting

        + +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/support/troubleshooting/installation.html b/stable/support/troubleshooting/installation.html new file mode 100644 index 00000000000..bf1686b9df3 --- /dev/null +++ b/stable/support/troubleshooting/installation.html @@ -0,0 +1,636 @@ + + + + + + + + + + + + + Troubleshooting installation issues | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Troubleshooting installation issues

        +
        +

        Webhooks

        +

        Scylla Operator provides several custom API resources that use webhooks to function properly.

        +

        Unfortunately, it is often the case that user’s clusters have modified SDN, that doesn’t extend to the control plane, and Kubernetes apiserver is not able to reach the pods that serve the webhook traffic. +Another common case are firewall rules that block the webhook traffic.

        +
        +

        Note

        +

        To be called a Kubernetes cluster, clusters are required to pass Kubernetes conformance test suite. +This suite includes tests that require Kubernetes apiserver to be able to reach webhook services.

        +
        +
        +

        Note

        +

        Before filing an issue, please make sure your cluster webhook traffic can reach your webhook services, independently of Scylla Operator resources.

        +
        +
        +

        EKS

        +
        +

        Custom CNI

        +

        EKS is currently breaking Kubernetes webhooks when used with custom CNI networking.

        +
        +

        Note

        +

        We advise you to avoid using such setups and use a conformant Kubernetes cluster that supports webhooks.

        +
        +

        There are some workarounds where you can reconfigure the webhook to use Ingress or hostNetwork instead, but it’s beyond a standard configuration that we support and not specific to the Scylla Operator.

        +
        +
        +
        +

        GKE

        +
        +

        Private clusters

        +

        If you use GKE private clusters you need to manually configure the firewall to allow webhook traffic. +You can find more information on how to do that in GKE private clusters docs.

        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/upgrade.html b/stable/upgrade.html new file mode 100644 index 00000000000..b666a2bc405 --- /dev/null +++ b/stable/upgrade.html @@ -0,0 +1,789 @@ + + + + + + + + + + + + + Upgrade of Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Upgrade of Scylla Operator

        +

        This page describes Scylla Operator upgrade procedures.
        +There are two generic update procedures - via Helm and via kubectl. Before upgrading, please check this page to find out +if your target version requires additional upgrade steps.

        +
        +

        Upgrade via Helm

        +

        Helm doesn’t support managing CustomResourceDefinition resources (#5871, #7735)
        +These are only created on first install and never updated. In order to update them, users have to do it manually.

        +

        Replace <release_name> with the name of your Helm release for Scylla Operator and replace <version> with the version number you want to install:

        +
          +
        1. Make sure Helm chart repository is up-to-date:

          +
          helm repo add scylla-operator https://storage.googleapis.com/scylla-operator-charts/stable
          +helm repo update
          +
          +
          +
        2. +
        3. Update CRD resources. We recommend using --server-side flag for kubectl apply, if your version supports it.

          +
          tmpdir=$( mktemp -d ) \
          +  && helm pull scylla-operator/scylla-operator --version <version> --untar --untardir "${tmpdir}" \
          +  && find "${tmpdir}"/scylla-operator/crds/ -name '*.yaml' -printf '-f=%p ' \
          +  | xargs kubectl apply
          +
          +
          +
        4. +
        5. Update Scylla Operator

          +
          helm upgrade --version <version> <release_name> scylla-operator/scylla-operator
          +
          +
          +
        6. +
        +
        +
        +

        Upgrade via kubectl

        +

        Replace <version> with the version number you want to install:

        +
          +
        1. Checkout source code of version you want to use:

          +
          git checkout <version>
          +
          +
          +
        2. +
        3. Manifests use rolling minor version tag, you may want to pin it to specific version:

          +
          find deploy/operator -name "*.yaml" | xargs sed --follow-symlinks -i -E "s^docker.io/scylladb/scylla-operator:[0-9]+\.[0-9]+^docker.io/scylladb/scylla-operator:<version>^g"
          +
          +
          +
        4. +
        5. Update Scylla Operator. We recommend using --server-side flag for kubectl apply, if your version supports it.

          +
          kubectl apply -f deploy/operator
          +
          +
          +
        6. +
        +
        +
        +
        +

        v1.2.0 -> v1.3.0

        +

        Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

        +
          +
        1. Checkout source code of v1.3.0:

          +
          git checkout v1.3.0
          +
          +
          +
        2. +
        3. Update Scylla Operator from deploy directory:

          +
          kubectl -n scylla-operator apply -f deploy/operator
          +
          +
          +
        4. +
        5. Wait until Scylla Operator is up and running:

          +
          kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
          +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
          +
          +
          +
        6. +
        +
        +
        +

        v1.1.0 -> v1.2.0

        +

        1.2.0 release brought a lot of changes to the Scylla Operator deployment process. +To properly update Scylla Operator one must delete old objects and install updated ones.

        +

        Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

        +
          +
        1. Checkout source code of v1.2.0:

          +
          git checkout v1.2.0
          +
          +
          +
        2. +
        3. Remove old scylla operator namespace - in our case it’s called scylla-operator-system:

          +
          kubectl delete namespace scylla-operator-system --wait=true
          +
          +
          +
        4. +
        5. Remove old webhooks:

          +
          kubectl delete MutatingWebhookConfiguration scylla-operator-mutating-webhook-configuration
          +kubectl delete ValidatingWebhookConfiguration scylla-operator-validating-webhook-configuration
          +
          +
          +
        6. +
        7. Install Scylla Operator from deploy directory:

          +
          kubectl -n scylla-operator apply -f deploy/operator
          +
          +
          +
        8. +
        9. Wait until Scylla Operator is up and running:

          +
          kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
          +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
          +
          +
          +
        10. +
        +
        +
        +

        v1.0.0 -> v1.1.0

        +

        During this update we will change probes and image for Scylla Operator. +A new version brings an automation for upgrade of sidecar image, so a rolling restart of managed Scylla clusters is expected.

        +
          +
        1. Get name of StatefulSet managing Scylla Operator

          +
          kubectl --namespace scylla-operator-system get sts --selector="control-plane=controller-manager"
          +
          +NAME                                 READY   AGE
          +scylla-operator-controller-manager   1/1     95m
          +
          +
          +
        2. +
        3. Change probes and used container image by applying following patch:

          +
          spec:
          +  template:
          +    spec:
          +      containers:
          +      - name: manager
          +        image: docker.io/scylladb/scylla-operator:1.1.0
          +        livenessProbe:
          +          httpGet:
          +            path: /healthz
          +            port: 8080
          +            scheme: HTTP
          +        readinessProbe:
          +          $retainKeys:
          +          - httpGet
          +          httpGet:
          +            path: /readyz
          +            port: 8080
          +            scheme: HTTP
          +
          +
          +

          To apply above patch save it to file (operator-patch.yaml for example) and apply to Operator StatefulSet:

          +
          kubectl -n scylla-operator-system patch sts scylla-operator-controller-manager --patch "$(cat operator-patch.yaml)"
          +
          +
          +
        4. +
        +
        +
        +

        v0.3.0 -> v1.0.0

        +

        Note: There’s an experimental migration procedure available here.

        +

        v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common +kind which is easier to disambiguate. (ScyllaCluster). +This change is backward incompatible, so Scylla cluster must be turned off and recreated from scratch. +In case you need to preserve your data, refer to backup and restore guide.

        +
          +
        1. Get list of existing Scylla clusters

          +
          kubectl -n scylla get cluster.scylla.scylladb.com
          +
          +NAME             AGE
          +simple-cluster   30m
          +
          +
          +
        2. +
        3. Delete each one of them

          +
          kubectl -n scylla delete cluster.scylla.scylladb.com simple-cluster
          +
          +
          +
        4. +
        5. Make sure you’re on v0.3.0 branch

          +
          git checkout v0.3.0
          +
          +
          +
        6. +
        7. Delete existing CRD and Operator

          +
          kubectl delete -f examples/generic/operator.yaml
          +
          +
          +
        8. +
        9. Checkout v1.0.0 version

          +
          git checkout v1.0.0
          +
          +
          +
        10. +
        11. Install new CRD and Scylla Operator

          +
          kubectl apply -f examples/common/operator.yaml
          +
          +
          +
        12. +
        13. Migrate your existing Scylla Cluster definition. Change apiVersion and kind from:

          +
          apiVersion: scylla.scylladb.com/v1alpha1
          +kind: Cluster
          +
          +
          +

          to:

          +
          apiVersion: scylla.scylladb.com/v1
          +kind: ScyllaCluster
          +
          +
          +
        14. +
        15. Once your cluster definition is ready, use kubectl apply to install fresh Scylla cluster.

        16. +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/v1.10/.buildinfo b/v1.10/.buildinfo new file mode 100644 index 00000000000..eb2c9fa7536 --- /dev/null +++ b/v1.10/.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: 6f8abfce81de3e269fc32bf11fcadaee +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/v1.10/.doctrees/contributing.doctree b/v1.10/.doctrees/contributing.doctree new file mode 100644 index 00000000000..d639e1d468e Binary files /dev/null and b/v1.10/.doctrees/contributing.doctree differ diff --git a/v1.10/.doctrees/eks.doctree b/v1.10/.doctrees/eks.doctree new file mode 100644 index 00000000000..fe367d5d843 Binary files /dev/null and b/v1.10/.doctrees/eks.doctree differ diff --git a/v1.10/.doctrees/environment.pickle b/v1.10/.doctrees/environment.pickle new file mode 100644 index 00000000000..c8cc35d948f Binary files /dev/null and b/v1.10/.doctrees/environment.pickle differ diff --git a/v1.10/.doctrees/generic.doctree b/v1.10/.doctrees/generic.doctree new file mode 100644 index 00000000000..e376910a049 Binary files /dev/null and b/v1.10/.doctrees/generic.doctree differ diff --git a/v1.10/.doctrees/gke.doctree b/v1.10/.doctrees/gke.doctree new file mode 100644 index 00000000000..f8cc2d8bd97 Binary files /dev/null and b/v1.10/.doctrees/gke.doctree differ diff --git a/v1.10/.doctrees/helm.doctree b/v1.10/.doctrees/helm.doctree new file mode 100644 index 00000000000..f3e2f61d9ca Binary files /dev/null and b/v1.10/.doctrees/helm.doctree differ diff --git a/v1.10/.doctrees/index.doctree b/v1.10/.doctrees/index.doctree new file mode 100644 index 00000000000..ddf1be327e0 Binary files /dev/null and b/v1.10/.doctrees/index.doctree differ diff --git a/v1.10/.doctrees/known-issues.doctree b/v1.10/.doctrees/known-issues.doctree new file mode 100644 index 00000000000..d97c59e2ea7 Binary files /dev/null and b/v1.10/.doctrees/known-issues.doctree differ diff --git a/v1.10/.doctrees/manager.doctree b/v1.10/.doctrees/manager.doctree new file mode 100644 index 00000000000..c4ae2933393 Binary files /dev/null and b/v1.10/.doctrees/manager.doctree differ diff --git a/v1.10/.doctrees/migration.doctree b/v1.10/.doctrees/migration.doctree new file mode 100644 index 00000000000..9a73fd8a195 Binary files /dev/null and b/v1.10/.doctrees/migration.doctree differ diff --git a/v1.10/.doctrees/monitoring.doctree b/v1.10/.doctrees/monitoring.doctree new file mode 100644 index 00000000000..b10ec805e0d Binary files /dev/null and b/v1.10/.doctrees/monitoring.doctree differ diff --git a/v1.10/.doctrees/nodeoperations/automatic-cleanup.doctree b/v1.10/.doctrees/nodeoperations/automatic-cleanup.doctree new file mode 100644 index 00000000000..d4130619265 Binary files /dev/null and b/v1.10/.doctrees/nodeoperations/automatic-cleanup.doctree differ diff --git a/v1.10/.doctrees/nodeoperations/index.doctree b/v1.10/.doctrees/nodeoperations/index.doctree new file mode 100644 index 00000000000..e3559146787 Binary files /dev/null and b/v1.10/.doctrees/nodeoperations/index.doctree differ diff --git a/v1.10/.doctrees/nodeoperations/maintenance-mode.doctree b/v1.10/.doctrees/nodeoperations/maintenance-mode.doctree new file mode 100644 index 00000000000..215b7627dcd Binary files /dev/null and b/v1.10/.doctrees/nodeoperations/maintenance-mode.doctree differ diff --git a/v1.10/.doctrees/nodeoperations/replace-node.doctree b/v1.10/.doctrees/nodeoperations/replace-node.doctree new file mode 100644 index 00000000000..8fb9fe1b429 Binary files /dev/null and b/v1.10/.doctrees/nodeoperations/replace-node.doctree differ diff --git a/v1.10/.doctrees/nodeoperations/restore.doctree b/v1.10/.doctrees/nodeoperations/restore.doctree new file mode 100644 index 00000000000..497b3385534 Binary files /dev/null and b/v1.10/.doctrees/nodeoperations/restore.doctree differ diff --git a/v1.10/.doctrees/nodeoperations/scylla-upgrade.doctree b/v1.10/.doctrees/nodeoperations/scylla-upgrade.doctree new file mode 100644 index 00000000000..ebfc288d7f8 Binary files /dev/null and b/v1.10/.doctrees/nodeoperations/scylla-upgrade.doctree differ diff --git a/v1.10/.doctrees/performance.doctree b/v1.10/.doctrees/performance.doctree new file mode 100644 index 00000000000..acf487b52b2 Binary files /dev/null and b/v1.10/.doctrees/performance.doctree differ diff --git a/v1.10/.doctrees/releases.doctree b/v1.10/.doctrees/releases.doctree new file mode 100644 index 00000000000..c71e60bc29c Binary files /dev/null and b/v1.10/.doctrees/releases.doctree differ diff --git a/v1.10/.doctrees/scylla-cluster-crd.doctree b/v1.10/.doctrees/scylla-cluster-crd.doctree new file mode 100644 index 00000000000..513837e33cc Binary files /dev/null and b/v1.10/.doctrees/scylla-cluster-crd.doctree differ diff --git a/v1.10/.doctrees/upgrade.doctree b/v1.10/.doctrees/upgrade.doctree new file mode 100644 index 00000000000..95cc34a351a Binary files /dev/null and b/v1.10/.doctrees/upgrade.doctree differ diff --git a/v1.10/.nojekyll b/v1.10/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/v1.10/404.html b/v1.10/404.html new file mode 100644 index 00000000000..067dc99ea74 --- /dev/null +++ b/v1.10/404.html @@ -0,0 +1,31 @@ + + + + + + + + + ScyllaDB + + + + + + + + + + + +
        +

        404

        +

        The ScyllaDB monster ate your page!

        +

        + Home +

        +
        + + + \ No newline at end of file diff --git a/v1.10/CNAME b/v1.10/CNAME new file mode 100644 index 00000000000..12aae904168 --- /dev/null +++ b/v1.10/CNAME @@ -0,0 +1 @@ +operator.docs.scylladb.com \ No newline at end of file diff --git a/v1.10/_images/logo.png b/v1.10/_images/logo.png new file mode 100644 index 00000000000..5bbfedad2ac Binary files /dev/null and b/v1.10/_images/logo.png differ diff --git a/v1.10/_sources/contributing.md.txt b/v1.10/_sources/contributing.md.txt new file mode 100644 index 00000000000..da5fc078732 --- /dev/null +++ b/v1.10/_sources/contributing.md.txt @@ -0,0 +1,155 @@ +# Contributing to Scylla Operator + +## Prerequisites + +To develop on scylla-operator, your environment must have the following: + +1. [Go 1.13](https://golang.org/dl/) + * Make sure [GOPATH](https://github.com/golang/go/wiki/SettingGOPATH) is set to `GOPATH=$HOME/go`. +2. [Kustomize v3.1.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/v3.1.0) +3. [kubebuilder v2.3.1](https://github.com/kubernetes-sigs/kubebuilder/releases/tag/v2.3.1) +4. [Docker](https://docs.docker.com/install/) +5. Git client installed +6. Github account + +To install all dependencies (Go, kustomize, kubebuilder, dep), simply run: +```bash +./install-dependencies.sh +``` + +## Initial Setup + +### Create a Fork + +From your browser navigate to [http://github.com/scylladb/scylla-operator](http://github.com/scylladb/scylla-operator) and click the "Fork" button. + +### Clone Your Fork + +Open a console window and do the following: + +```bash +# Create the scylla operator repo path +mkdir -p $GOPATH/src/github.com/scylladb + +# Navigate to the local repo path and clone your fork +cd $GOPATH/src/github.com/scylladb + +# Clone your fork, where is your GitHub account name +git clone https://github.com//scylla-operator.git +``` + +### Add Upstream Remote + +First you will need to add the upstream remote to your local git: +```bash +# Add 'upstream' to the list of remotes +git remote add upstream https://github.com/scylladb/scylla-operator.git + +# Verify the remote was added +git remote -v +``` +Now you should have at least `origin` and `upstream` remotes. You can also add other remotes to collaborate with other contributors. + +## Development + +To add a feature or to make a bug fix, you will need to create a branch in your fork and then submit a pull request (PR) from the branch. + +### Building the project + +You can build the project using the Makefile commands: +* Open the Makefile and change the `IMG` environment variable to a repository you have access to. +* Run `make docker-push` and wait for the image to be built and uploaded in your repo. + +### Create a Branch + +From a console, create a new branch based on your fork and start working on it: + +```bash +# Ensure all your remotes are up to date with the latest +git fetch --all + +# Create a new branch that is based off upstream master. Give it a simple, but descriptive name. +# Generally it will be two to three words separated by dashes and without numbers. +git checkout -b feature-name upstream/master +``` + +Now you are ready to make the changes and commit to your branch. + +### Updating Your Fork + +During the development lifecycle, you will need to keep up-to-date with the latest upstream master. As others on the team push changes, you will need to `rebase` your commits on top of the latest. This avoids unnecessary merge commits and keeps the commit history clean. + +Whenever you need to update your local repository, you never want to merge. You **always** will rebase. Otherwise you will end up with merge commits in the git history. If you have any modified files, you will first have to stash them (`git stash save -u ""`). + +```bash +git fetch --all +git rebase upstream/master +``` + +Rebasing is a very powerful feature of Git. You need to understand how it works or else you will risk losing your work. Read about it in the [Git documentation](https://git-scm.com/docs/git-rebase), it will be well worth it. In a nutshell, rebasing does the following: +- "Unwinds" your local commits. Your local commits are removed temporarily from the history. +- The latest changes from upstream are added to the history +- Your local commits are re-applied one by one +- If there are merge conflicts, you will be prompted to fix them before continuing. Read the output closely. It will tell you how to complete the rebase. +- When done rebasing, you will see all of your commits in the history. + +## Submitting a Pull Request + +Once you have implemented the feature or bug fix in your branch, you will open a PR to the upstream repo. Before opening the PR ensure you have added unit tests, are passing the integration tests, cleaned your commit history, and have rebased on the latest upstream. + +In order to open a pull request (PR) it is required to be up to date with the latest changes upstream. If other commits are pushed upstream before your PR is merged, you will also need to rebase again before it will be merged. + +### Commit History + +To prepare your branch to open a PR, you will need to have the minimal number of logical commits so we can maintain +a clean commit history. Most commonly a PR will include a single commit where all changes are squashed, although +sometimes there will be multiple logical commits. + +```bash +# Inspect your commit history to determine if you need to squash commits +git log + +# Rebase the commits and edit, squash, or even reorder them as you determine will keep the history clean. +# In this example, the last 5 commits will be opened in the git rebase tool. +git rebase -i HEAD~5 +``` + +Once your commit history is clean, ensure you have based on the [latest upstream](#updating-your-fork) before you open the PR. + +### Commit messages + +Please make the first line of your commit message a summary of the change that a user (not a developer) of Operator would like to read, +and prefix it with the most relevant directory of the change followed by a colon. +The changelog gets made by looking at just these first lines so make it good! + +If you have more to say about the commit, then enter a blank line and carry on the description. +Remember to say why the change was needed - the commit itself shows what was changed. + +Writing more is better than less. Comparing the behaviour before the change to that after the change is very useful. +Imagine you are writing to yourself in 12 months time when you've forgotten everything about what you just did, and you need to get up to speed quickly. + +If the change fixes an issue then write Fixes #1234 in the commit message. +This can be on the subject line if it will fit. If you don't want to close the associated issue just put #1234 and the change will get linked into the issue. + +Here is an example of a short commit message: + +``` +sidecar: log on reconcile loop - fixes #1234 +``` + +And here is an example of a longer one: +``` + +api: now supports host networking (#1234) + +The operator CRD now has a "network" property that can be used to +select host networking as well as setting the apropriate DNS policy. + +Fixes #1234 +``` + +### Submitting + +Go to the [Scylla Operator github](https://www.github.com/scylladb/scylla-operator) to open the PR. If you have pushed recently, you should see an obvious link to open the PR. If you have not pushed recently, go to the Pull Request tab and select your fork and branch for the PR. + +After the PR is open, you can make changes simply by pushing new commits. Your PR will track the changes in your fork and update automatically. diff --git a/v1.10/_sources/eks.md.txt b/v1.10/_sources/eks.md.txt new file mode 100644 index 00000000000..ecfe0f0d1bb --- /dev/null +++ b/v1.10/_sources/eks.md.txt @@ -0,0 +1,125 @@ +# Deploying Scylla on EKS + +This guide is focused on deploying Scylla on EKS with improved performance. +Performance tricks used by the script won't work with different machine tiers. +It sets up the kubelets on EKS nodes to run with [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and uses [local sdd disks](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ssd-instance-store.html) in RAID0 for maximum performance. + +Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the [general guide](generic.md). + +## TL;DR; + +If you don't want to run the commands step-by-step, you can just run a script that will set everything up for you: +```bash +# Edit according to your preference +EKS_REGION=us-east-1 +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c + +# From inside the examples/eks folder +cd examples/eks +./eks.sh -z "$EKS_ZONES" -r "$EKS_REGION" +``` + +After you deploy, see how you can [benchmark your cluster with cassandra-stress](#benchmark-with-cassandra-stress). + +## Walkthrough + +### EKS Setup + +#### Configure environment variables + +First of all, we export all the configuration options as environment variables. +Edit according to your own environment. + +``` +EKS_REGION=us-east-1 +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c +CLUSTER_NAME=scylla-demo +``` + +#### Creating an EKS cluster + +For this guide, we'll create an EKS cluster with the following: + +* A NodeGroup of 3 `i3-2xlarge` Nodes, where the Scylla Pods will be deployed. These nodes will only accept pods having `scylla-clusters` toleration. + +``` + - name: scylla-pool + instanceType: i3.2xlarge + desiredCapacity: 3 + labels: + scylla.scylladb.com/node-type: scylla + taints: + role: "scylla-clusters:NoSchedule" + ssh: + allow: true + kubeletExtraConfig: + cpuManagerPolicy: static +``` + +* A NodeGroup of 4 `c4.2xlarge` Nodes to deploy `cassandra-stress` later on. These nodes will only accept pods having `cassandra-stress` toleration. + +``` + - name: cassandra-stress-pool + instanceType: c4.2xlarge + desiredCapacity: 4 + labels: + pool: "cassandra-stress-pool" + taints: + role: "cassandra-stress:NoSchedule" + ssh: + allow: true +``` + +* A NodeGroup of 1 `i3.large` Node, where the monitoring stack and operator will be deployed. +``` + - name: monitoring-pool + instanceType: i3.large + desiredCapacity: 1 + labels: + pool: "monitoring-pool" + ssh: + allow: true +``` + +### Prerequisites + +#### Installing script third party dependencies + +Script requires several dependencies: +- eksctl - See: https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html +- kubectl - See: https://kubernetes.io/docs/tasks/tools/install-kubectl/ + +#### Setting up nodes for ScyllaDB + +ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you'll first need to form a RAID array from those disks. +`NodeConfig` performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in [Performance tuning](performance.md) section of ScyllaDB Operator's documentation. + +Deploy `NodeConfig` to let it take care of the above operations: +``` +kubectl apply --server-side -f examples/gke/nodeconfig-alpha.yaml +``` + +#### Deploying Local Volume Provisioner + +Afterwards, deploy ScyllaDB's [Local Volume Provisioner](https://github.com/scylladb/k8s-local-volume-provisioner), capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays. +``` +kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/ +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml +``` + +### Installing the Scylla Operator and Scylla + +Now you can follow the [generic guide](generic.md) to launch your Scylla cluster in a highly performant environment. + +#### Accessing the database + +Instructions on how to access the database can also be found in the [generic guide](generic.md). + +### Deleting an EKS cluster + +Once you are done with your experiments delete your cluster using the following command: + +``` +eksctl delete cluster "${CLUSTER_NAME}" +``` diff --git a/v1.10/_sources/generic.md.txt b/v1.10/_sources/generic.md.txt new file mode 100644 index 00000000000..8a999e4d9d8 --- /dev/null +++ b/v1.10/_sources/generic.md.txt @@ -0,0 +1,375 @@ +# Deploying Scylla on a Kubernetes Cluster + +This is a guide to deploy a Scylla Cluster in a generic Kubernetes environment, meaning that Scylla will not be deployed with the ideal performance. +Scylla performs the best when it has fast disks and direct access to the cpu. +This requires some extra setup, which is platform-specific. +For specific configuration and setup, check for details about your particular environment: + +* [GKE](gke.md) + +## Prerequisites + +* A Kubernetes cluster +* A [Storage Class](https://kubernetes.io/docs/concepts/storage/storage-classes/) to provision [PersistentVolumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/). +* Helm 3 installed, Go to the [helm docs](https://docs.helm.sh/using_helm/#installing-helm) if you need to install it. + Make sure that you enable the [stable repository](https://github.com/helm/charts#how-do-i-enable-the-stable-repository-for-helm-3) + +## Running locally + +Running kubernetes locally is a daunting and error prone task. +Fortunately there are ways to make life easier and [Minikube](https://minikube.sigs.k8s.io/docs/) makes it a breeze. + +We need to give minikube a little bit more resources than default so start minikube like this: +```console +minikube start --cpus=6 +``` + +Then make kubectl aware of this local installation like this: +```console +eval $(minikube docker-env) +``` + +## Download Scylla Operator +In this guide you will be using the examples and manifests from [Scylla Operator repository](https://github.com/scylladb/scylla-operator), so start off by cloning it to your local machine. +```console +git clone git@github.com:scylladb/scylla-operator.git +cd scylla-operator +``` + +## Deploy Cert Manager +First deploy Cert Manager, you can either follow [upsteam instructions](https://cert-manager.io/docs/installation/kubernetes/) or use following command: + +```console +kubectl apply -f examples/common/cert-manager.yaml +``` +This will install Cert Manager to provision a self-signed certificate. + +Once it's deployed, wait until Cert Manager is ready: + +```console +kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io +kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook +``` + +## Deploy Scylla Operator + +Deploy the Scylla Operator using the following commands: + +```console +kubectl apply -f examples/common/operator.yaml +``` + +This will install the operator in namespace `scylla-operator`. +Wait until it's ready: + +```console +kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator +``` + +If you want to check the logs of the operator you can do so with: + + ```console +kubectl -n scylla-operator logs deployment.apps/scylla-operator +``` + +## Create and Initialize a Scylla Cluster + +Now that the operator is running, we can create an instance of a Scylla cluster by creating an instance of the `clusters.scylla.scylladb.com` resource. +Some of that resource's values are configurable, so feel free to browse `cluster.yaml` and tweak the settings to your liking. +Full details for all the configuration options can be found in the [Scylla Cluster CRD documentation](scylla-cluster-crd.md). + +When you are ready to create a Scylla cluster, simply run: + +```console +kubectl create -f examples/generic/cluster.yaml +``` + +We can verify that a Kubernetes object has been created that represents our new Scylla cluster with the command below. +This is important because it shows that has successfully extended Kubernetes to make Scylla clusters a first class citizen in the Kubernetes cloud-native environment. + +```console +kubectl -n scylla get ScyllaCluster +``` + +Checking the pods that are created is as easy as: + +```console +kubectl -n scylla get pods +``` + +The output should be something like: + +```console +NAME READY STATUS RESTARTS AGE +simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 9m49s +simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 7m43s +simple-cluster-us-east-1-us-east-1a-2 2/2 Running 0 6m46s +``` + +It is important to note that the operator creates these instances according to a pattern. +This pattern is as follows: `CLUSTER_NAME-DATACENTER_NAME-RACK_NAME-INSTANCE_NUMBER` as specified in `cluster.yaml`. + +In the above example we have the following properties: + + - CLUSTER_NAME: `simple-cluster` + - DATACENTER_NAME: `us-east-1` + - RACK_NAME: `us-east-1a` + - INSTANCE_NUMBER: An automatically generated number attached to the pod name. + +We picked the names to resemble something you can find in a cloud service but this is inconsequential, they can be set to anything you want. + +To check if all the desired members are running, you should see the same number of entries from the following command as the number of members that was specified in `cluster.yaml`: + +```console +kubectl -n scylla get pod -l app=scylla +``` + +You can also track the state of a Scylla cluster from its status. To check the current status of a Cluster, run: + +```console +kubectl -n scylla describe ScyllaCluster simple-cluster +``` + +Checking the logs of the running scylla instances can be done like this: + +```console +kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 scylla +``` + +### Configure host networking + +To squeeze the most out of your deployment it is sometimes necessary to employ [host networking](https://kubernetes.io/docs/concepts/services-networking/). +To enable this the CRD allows for specifying a `network` parameter as such: + +```yaml +version: 4.0.0 + agentVersion: 2.0.2 + cpuset: true + network: + hostNetworking: true +``` + +This will result in hosts network to be used for the Scylla Stateful Set deployment. + +### Configure container kernel parameters + +Sometimes it is necessary to run the container with different kernel parameters. +In order to support this, the Scylla Operator defines a cluster property `sysctls` that is a list of the desired key-value pairs to set. + +___For example___: To increase the number events available for asynchronous IO processing in the Linux kernel to N set sysctls to`fs.aio-max-nr=N`. + +```yaml +spec: + sysctls: + - "fs.aio-max-nr=2097152" +``` + +### Deploying Alternator + +The operator is also capable of deploying [Alternator](https://www.scylladb.com/alternator/) instead of the regular Scylla. +This requires a small change in the cluster definition. +Change the `cluster.yaml` file from this: +```yaml +spec: + version: 4.0.0 + agentVersion: 2.0.2 + developerMode: true + datacenter: + name: us-east-1 +``` +to this: +```yaml +spec: + version: 4.0.0 + alternator: + port: 8000 + writeIsolation: only_rmw_uses_lwt + agentVersion: 2.0.2 + developerMode: true + datacenter: + name: us-east-1 +``` +You can specify whichever port you want. + +You must provide desired write isolation, supported values are: "always", "forbid_rmw", "only_rmw_uses_lwt". +Difference between those isolation levels can be found in Scylla Alternator documentation. + +Once this is done the regular CQL ports will no longer be available, the cluster is a pure Alienator cluster. + +## Accessing the Database + +* From kubectl: + +To get a cqlsh shell in your new Cluster: +```console +kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- cqlsh +> DESCRIBE KEYSPACES; +``` + + +* From inside a Pod: + +When you create a new Cluster, automatically creates a Service for the clients to use in order to access the Cluster. +The service's name follows the convention `-client`. +You can see this Service in your cluster by running: +```console +kubectl -n scylla describe service simple-cluster-client +``` +Pods running inside the Kubernetes cluster can use this Service to connect to Scylla. +Here's an example using the [Python Driver](https://github.com/datastax/python-driver): +```python +from cassandra.cluster import Cluster + +cluster = Cluster(['simple-cluster-client.scylla.svc']) +session = cluster.connect() +``` + +If you are running the Alternator you can access the API on the port you specified using plain http. + +## Configure Scylla + +The operator can take a ConfigMap and apply it to the scylla.yaml configuration file. +This is done by adding a ConfigMap to Kubernetes and refering to this in the Rack specification. +The ConfigMap is just a file called `scylla.yaml` that has the properties you want to change in it. +The operator will take the default properties for the rest of the configuration. + +* Create a ConfigMap the default name that the operator uses is `scylla-config`: +```console +kubectl create configmap scylla-config -n scylla --from-file=/path/to/scylla.yaml +``` +* Wait for the mount to propagate and then restart the cluster: +```console +kubectl rollout restart -n scylla statefulset/simple-cluster-us-east-1-us-east-1a +``` +* The new config should be applied automatically by the operator, check the logs to be sure. + +Configuring `cassandra-rackdc.properties` is done by adding the file to the same mount as `scylla.yaml`. +```console +kubectl create configmap scylla-config -n scylla --from-file=/tmp/scylla.yaml --from-file=/tmp/cassandra-rackdc.properties -o yaml --dry-run | kubectl replace -f - +``` +The operator will then apply the overridable properties `prefer_local` and `dc_suffix` if they are available in the provided mounted file. + +## Configure Scylla Manager Agent + +The operator creates a second container for each scylla instance that runs [Scylla Manager Agent](https://hub.docker.com/r/scylladb/scylla-manager-agent). +This container serves as a sidecar and it's the main endpoint for interacting with Scylla API. +The Scylla Manager Agent can be configured with various things such as the security token used to allow access to Scylla API and storage providers for backups. + +To configure the agent you just create a new secret called _scylla-agent-config-secret_ and populate it with the contents in the `scylla-manager-agent.yaml` file like this: +```console +kubectl create secret -n scylla generic scylla-agent-config-secret --from-file scylla-manager-agent.yaml +``` + +See [Scylla Manager Agent configuration](https://docs.scylladb.com/operating-scylla/manager/2.0/agent-configuration-file/) for a complete reference of the Scylla Manager agent config file. + +### Scylla Manager Agent auth token + +Operator provisions Agent auth token by copying value from user provided config secret or auto generates it if it's empty. +To check which value is being used, decode content of `-auth-token` secret. +To change it simply remove the secret. Operator will create a new one. To pick up the change in the cluster, initiate a rolling restart. + +## Set up monitoring + +To set up monitoring using Prometheus and Grafana follow [this guide](monitoring.md). + +## Scale Up + +The operator supports scale up of a rack as well as addition of new racks. To make the changes, you can use: +```console +kubectl -n scylla edit ScyllaCluster simple-cluster +``` +* To scale up a rack, change the `Spec.Members` field of the rack to the desired value. +* To add a new rack, append the `racks` list with a new rack. Remember to choose a different rack name for the new rack. +* After editing and saving the yaml, check your cluster's Status and Events for information on what's happening: +```console +kubectl -n scylla describe ScyllaCluster simple-cluster +``` + +## Benchmark with cassandra-stress + +After deploying our cluster along with the monitoring, we can benchmark it using cassandra-stress and see its performance in Grafana. We have a mini cli that generates Kubernetes Jobs that run cassandra-stress against a cluster. + +> Because cassandra-stress doesn't scale well to multiple cores, we use multiple jobs with a small core count for each + +```bash + +# Run a benchmark with 10 jobs, with 6 cpus and 50.000.000 operations each. +# Each Job will throttle throughput to 30.000 ops/sec for a total of 300.000 ops/sec. +hack/cass-stress-gen.py --num-jobs=10 --cpu=6 --memory=20G --ops=50000000 --limit=30000 +kubectl apply -f scripts/cassandra-stress.yaml +``` + +Make sure you set the proper arguments in case you have altered things such as _name_ or _namespace_. + +```bash +./hack/cass-stress-gen.py -h +usage: cass-stress-gen.py [-h] [--num-jobs NUM_JOBS] [--name NAME] [--namespace NAMESPACE] [--scylla-version SCYLLA_VERSION] [--host HOST] [--cpu CPU] [--memory MEMORY] [--ops OPS] [--threads THREADS] [--limit LIMIT] + [--connections-per-host CONNECTIONS_PER_HOST] [--print-to-stdout] [--nodeselector NODESELECTOR] + +Generate cassandra-stress job templates for Kubernetes. + +optional arguments: + -h, --help show this help message and exit + --num-jobs NUM_JOBS number of Kubernetes jobs to generate - defaults to 1 + --name NAME name of the generated yaml file - defaults to cassandra-stress + --namespace NAMESPACE + namespace of the cassandra-stress jobs - defaults to "default" + --scylla-version SCYLLA_VERSION + version of scylla server to use for cassandra-stress - defaults to 4.0.0 + --host HOST ip or dns name of host to connect to - defaults to scylla-cluster-client.scylla.svc + --cpu CPU number of cpus that will be used for each job - defaults to 1 + --memory MEMORY memory that will be used for each job in GB, ie 2G - defaults to 2G * cpu + --ops OPS number of operations for each job - defaults to 10000000 + --threads THREADS number of threads used for each job - defaults to 50 * cpu + --limit LIMIT rate limit for each job - defaults to no rate-limiting + --connections-per-host CONNECTIONS_PER_HOST + number of connections per host - defaults to number of cpus + --print-to-stdout print to stdout instead of writing to a file + --nodeselector NODESELECTOR + nodeselector limits cassandra-stress pods to certain nodes. Use as a label selector, eg. --nodeselector role=scylla +``` +While the benchmark is running, open up Grafana and take a look at the monitoring metrics. + +After the Jobs finish, clean them up with: +```bash +kubectl delete -f scripts/cassandra-stress.yaml +``` + +## Scale Down + +The operator supports scale down of a rack. To make the changes, you can use: +```console +kubectl -n scylla edit ScyllaCluster simple-cluster +``` +* To scale down a rack, change the `Spec.Members` field of the rack to the desired value. +* After editing and saving the yaml, check your cluster's Status and Events for information on what's happening: +```console +kubectl -n scylla describe ScyllaCluster simple-cluster +``` + +## Clean Up + +To clean up all resources associated with this walk-through, you can run the commands below. + +**NOTE:** this will destroy your database and delete all of its associated data. + +```console +kubectl delete -f examples/generic/cluster.yaml +kubectl delete -f examples/common/operator.yaml +kubectl delete -f examples/common/cert-manager.yaml +``` + +## Troubleshooting + +If the cluster does not come up, the first step would be to examine the operator's logs: + +```console +kubectl -n scylla-operator logs deployment.apps/scylla-operator +``` + +If everything looks OK in the operator logs, you can also look in the logs for one of the Scylla instances: + +```console +kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 +``` diff --git a/v1.10/_sources/gke.md.txt b/v1.10/_sources/gke.md.txt new file mode 100644 index 00000000000..04fe721f224 --- /dev/null +++ b/v1.10/_sources/gke.md.txt @@ -0,0 +1,167 @@ +# Deploying Scylla on GKE + +This guide is focused on deploying Scylla on GKE with maximum performance (without any persistence guarantees). +It sets up the kubelets on GKE nodes to run with [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and uses [local sdd disks](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/local-ssd) in RAID0 for maximum performance. + +Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the [general guide](generic.md). + +## TL;DR; + +If you don't want to run the commands step-by-step, you can just run a script that will set everything up for you: +```bash +# Edit according to your preference +GCP_USER=$(gcloud config list account --format "value(core.account)") +GCP_PROJECT=$(gcloud config list project --format "value(core.project)") +GCP_ZONE=us-west1-b + +# From inside the examples/gke folder +cd examples/gke +./gke.sh -u "$GCP_USER" -p "$GCP_PROJECT" -z "$GCP_ZONE" + +# Example: +# ./gke.sh -u yanniszark@arrikto.com -p gke-demo-226716 -z us-west1-b +``` + +:warning: Make sure to pass a ZONE (ex.: us-west1-b) and not a REGION (ex.: us-west1) or it will deploy nodes in each ZONE available in the region. + +After you deploy, see how you can [benchmark your cluster with cassandra-stress](#benchmark-with-cassandra-stress). + +## Walkthrough + +### Google Kubernetes Engine Setup + +#### Configure environment variables + +First of all, we export all the configuration options as environment variables. +Edit according to your own environment. + +``` +GCP_USER=$( gcloud config list account --format "value(core.account)" ) +GCP_PROJECT=$( gcloud config list project --format "value(core.project)" ) +GCP_REGION=us-west1 +GCP_ZONE=us-west1-b +CLUSTER_NAME=scylla-demo +CLUSTER_VERSION=$( gcloud container get-server-config --zone ${GCP_ZONE} --format "value(validMasterVersions[0])" ) +``` + +#### Creating a GKE cluster + +First we need to change kubelet CPU Manager policy to static by providing a config file. Create file called `systemconfig.yaml` with the following content: +``` +kubeletConfig: + cpuManagerPolicy: static +``` + +Then we'll create a GKE cluster with the following: + +1. A NodePool of 2 `n1-standard-8` Nodes, where the operator and the monitoring stack will be deployed. These are generic Nodes and their free capacity can be used for other purposes. + ``` + gcloud container \ + clusters create "${CLUSTER_NAME}" \ + --cluster-version "${CLUSTER_VERSION}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-8" \ + --num-nodes "2" \ + --disk-type "pd-ssd" --disk-size "20" \ + --image-type "UBUNTU_CONTAINERD" \ + --system-config-from-file=systemconfig.yaml \ + --enable-stackdriver-kubernetes \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +2. A NodePool of 2 `n1-standard-32` Nodes to deploy `cassandra-stress` later on. + + ``` + gcloud container --project "${GCP_PROJECT}" \ + node-pools create "cassandra-stress-pool" \ + --cluster "${CLUSTER_NAME}" \ + --zone "${GCP_ZONE}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-32" \ + --num-nodes "2" \ + --disk-type "pd-ssd" --disk-size "20" \ + --node-taints role=cassandra-stress:NoSchedule \ + --image-type "UBUNTU_CONTAINERD" \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +3. A NodePool of 4 `n1-standard-32` Nodes, where the Scylla Pods will be deployed. Each of these Nodes has 8 local NVMe SSDs attached, which are provided as [raw block devices](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/local-ssd#raw-block). It is important to disable `autoupgrade` and `autorepair`. Automatic cluster upgrade or node repair has a hard timeout after which it no longer respect PDBs and force deletes the Compute Engine instances, which also deletes all data on the local SSDs. At this point, it's better to handle upgrades manually, with more control over the process and error handling. + ``` + gcloud container \ + node-pools create "scylla-pool" \ + --cluster "${CLUSTER_NAME}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-32" \ + --num-nodes "4" \ + --disk-type "pd-ssd" --disk-size "20" \ + --local-nvme-ssd-block count="8" \ + --node-taints role=scylla-clusters:NoSchedule \ + --node-labels scylla.scylladb.com/node-type=scylla \ + --image-type "UBUNTU_CONTAINERD" \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +#### Setting Yourself as `cluster-admin` +> (By default GKE doesn't give you the necessary RBAC permissions) + +Get the credentials for your new cluster +``` +gcloud container clusters get-credentials "${CLUSTER_NAME}" --zone="${GCP_ZONE}" +``` + +Create a ClusterRoleBinding for your user. +In order for this to work you need to have at least permission `container.clusterRoleBindings.create`. +The easiest way to obtain this permission is to enable the `Kubernetes Engine Admin` role for your user in the GCP IAM web interface. +``` +kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user "${GCP_USER}" +``` + + +### Prerequisites + +#### Setting up nodes for ScyllaDB + +ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you'll first need to form a RAID array from those disks. +`NodeConfig` performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in [Performance tuning](performance.md) section of ScyllaDB Operator's documentation. + +Deploy `NodeConfig` to let it take care of the above operations: +``` +kubectl apply --server-side -f examples/gke/nodeconfig-alpha.yaml +``` + +#### Deploying Local Volume Provisioner + +Afterwards, deploy ScyllaDB's [Local Volume Provisioner](https://github.com/scylladb/k8s-local-volume-provisioner), capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays. +``` +kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/ +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml +``` + +### Deploy Scylla cluster +In order for the example to work you need to modify the cluster definition in the following way: + +``` +sed -i "s//${GCP_REGION}/g;s//${GCP_ZONE}/g" examples/gke/cluster.yaml +``` + +This will inject your region and zone into the cluster definition so that it matches the kubernetes cluster you just created. + +### Installing the Scylla Operator and Scylla + +Now you can follow the [generic guide](generic.md) to install the operator and launch your Scylla cluster in a highly performant environment. + +#### Accessing the database + +Instructions on how to access the database can also be found in the [generic guide](generic.md). + +### Deleting a GKE cluster + +Once you are done with your experiments delete your cluster using the following command: + +``` +gcloud container --project "${GCP_PROJECT}" clusters delete --zone "${GCP_ZONE}" "${CLUSTER_NAME}" +``` diff --git a/v1.10/_sources/helm.md.txt b/v1.10/_sources/helm.md.txt new file mode 100644 index 00000000000..56fbe9620ac --- /dev/null +++ b/v1.10/_sources/helm.md.txt @@ -0,0 +1,339 @@ +# Deploying Scylla stack using Helm Charts + +In this example we will install Scylla stack on Kubernetes. This includes the following components: +- Scylla Operator +- Scylla Manager +- Scylla + +We will use Minikube K8s cluster, but this could be any K8s cluster supported by the Scylla Operator. + +### Prerequisites + +- Kubernetes 1.16+ +- Helm 3+ + +### TL;DR + +``` +helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable +helm repo update +kubectl apply -f examples/common/cert-manager.yaml +helm install scylla-operator scylla/scylla-operator --create-namespace --namespace scylla-operator +helm install scylla-manager scylla/scylla-manager --create-namespace --namespace scylla-manager +helm install scylla scylla/scylla --create-namespace --namespace scylla +``` + +### Deploy Cert Manager + +This step is optional if you want to use your own certificate. +If you don't have one, make sure to not disable autogeneration using Scylla Operator Helm Chart. + +First deploy Cert Manager, you can either follow [upsteam instructions](https://cert-manager.io/docs/installation/kubernetes/) or use following command: + +```console +kubectl apply -f examples/common/cert-manager.yaml +``` + +Once it's deployed, wait until all Cert Manager pods will enter into Running state: + +```console +kubectl wait -n cert-manager --for=condition=ready pod -l app=cert-manager --timeout=60s +``` + +### Helm Chart repository + +To install Scylla Helm Chart repository execute the following commands: +``` +helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable +helm repo update +``` + +Then you can search through repository, it should contain at least three Helm charts: +``` +helm search repo scylla +NAME CHART VERSION APP VERSION DESCRIPTION +scylla/scylla 1.0.1 v1.0.1 Scylla is a close-to-the-hardware rewrite of Ca... +scylla/scylla-manager 1.0.1 v1.0.1 Scylla Manager automates database operations. +scylla/scylla-operator 1.0.1 v1.0.1 Scylla Operator is a Kubernetes Operator for ma... +``` + +All these charts should be installable without any need of customizing (defaults are provided). +Although Helm is used for this particular reason, so lets customize them a bit. + +### Scylla Operator Chart + +This chart is very simple, most interesting customizable fields are `image`, `resources` and `webhook`. +All others can be looked up in Chart source in Scylla Operator repository. + +#### image + +Image allows to define which Scylla Operator image will be used. By default it downloads the image from main +Docker Hub repository, using version defined in Helm Chart. +You can also change `pullPolicy` if default one does not +fullfill your needs. In [Kubernetes documentation](https://kubernetes.io/docs/concepts/containers/images/) you +can read more about different pull policies. + +Image URL will be composed based on these fields in follwing pattern: +`repository/scylla-operator:tag` +```yaml +image: + repository: scylladb + pullPolicy: IfNotPresent + tag: "" +``` + +#### resources + +You can customize how much resources will be allocated for Operator pods via `resource` field: +```yaml +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 32Mi +``` + +To read more about resource specification, follow [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +#### webhook + +Webhook field allows to decide whether you want to use autogenerated self-signed certificate using Cert Manager or +whether you want to provide your own certificate. + +`createSelfSignedCertificate` specifies whether a self-signed certificate should be created using Cert Manager +`certificateSecretName`: name of a secret containing custom certificate. + +```yaml +webhook: + createSelfSignedCertificate: true + certificateSecretName: "" +``` + +#### Customization + +You can customize all these fields and others by providing file containing desired values. +Content of this file will overwrite default values. + +You can find an example in Scylla Operator repository under `examples/helm/values.operator.yaml` + +#### Installation + +To deploy Scylla Operator using customized values file execute the following: +``` +helm install scylla-operator scylla/scylla-operator --values examples/helm/values.operator.yaml --create-namespace --namespace scylla-operator +``` + +### Scylla Helm Chart + +Scylla Chart allows to customize and deploy Scylla cluster. +By default Scylla Helm charts deploys working Scylla cluster, but of course we can customize it. + +#### Customization + +Versions of images used in the cluster can be set via `scyllaImage` and `agentImage` +```yaml +scyllaImage: + repository: scylladb/scylla + tag: 4.3.0 + +agentImage: + repository: scylladb/scylla-manager-agent + tag: 2.2.1 +``` + +A minimal Scylla cluster can be expressed as: +```yaml +datacenter: us-east-1 +racks: +- name: us-east-1b + members: 2 + storage: + capacity: 5G + resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 1 + memory: 1Gi +``` + +Above cluster will use 4.3.0 Scylla, 2.2.1 Scylla Manager Agent sidecar and will have a single rack having 2 nodes. +Each node will have a single CPU and 1 GiB of memory. + +For other customizable fields, please refer to [ScyllaCluster CRD definition](scylla-cluster-crd.md). +CRD Rack Spec and Helm Chart Rack should have the same fields. + +#### Installation + +To deploy Scylla cluster using customzied values file execute the following command: +``` +helm install scylla scylla/scylla --values examples/helm/values.cluster.yaml --create-namespace --namespace scylla +``` + +Scylla Operator will provision this cluster on your K8s environment. + +### Scylla Manager Helm Chart + +Scylla Manager Chart allows to customize and deploy Scylla Manager in K8s environment. +Scylla Manager consist of two applications (Scylla Manager itself and Scylla Manager Controller) and additional Scylla cluster. + +To read more about Scylla Manager see [Manager guide](manager.md). + +#### Scylla Manager + +To set version of used Scylla Manager you can use `image` field: +```yaml +image: + repository: scylladb + pullPolicy: IfNotPresent + tag: 2.2.1 +``` +To control how many resources are allocated for Scylla Manager use `resource` field: +```yaml +resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 500m + memory: 500Mi +``` + +#### Scylla Manager Controller + +Similarly Scylla Manager Controller image can be customized: + +```yaml +controllerImage: + repository: scylladb + pullPolicy: IfNotPresent + tag: "" +``` + +And allocated resources: +```yaml +controllerResources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi +``` + +#### Scylla + +To customize internal Scylla instance dedicated to Scylla Manager, see guide above customizing Scylla Helm Chart. +It's definition should land as a `scylla` field. + +#### Customization + +All others customizable fields can be looked up in Chart source in Scylla Operator repository. + +#### Installation + +To deploy Scylla Manager using customized values file execute the following command: +``` +helm install scylla-manager scylla/scylla-manager --values examples/helm/values.manager.yaml --create-namespace --namespace scylla-manager +``` + +## Results + +Scylla need some time to bootstrap all nodes, but after some time you should be ready to roll. It was simple isn't it? +You can validate if everything was set up correctly by looking at the all resources created in used namespaces. + +Scylla Operator: +```shell +$ kubectl -n scylla-operator get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-operator-5dbcb54f5c-vjm4m 1/1 Running 0 51s +pod/scylla-operator-5dbcb54f5c-wfjbw 1/1 Running 0 51s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-operator-webhook ClusterIP 10.105.207.130 443/TCP 51s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/scylla-operator 2/2 2 2 51s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/scylla-operator-5dbcb54f5c 2 2 2 51s + +``` + +Operator is running! + +Scylla Manager: +```shell +$ kubectl -n scylla-manager get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-manager-669db64dd-bcm4v 1/1 Running 0 89s +pod/scylla-manager-controller-844ccc56c4-drbth 1/1 Running 0 89s +pod/scylla-manager-controller-844ccc56c4-rhwqx 1/1 Running 0 89s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-manager ClusterIP 10.105.231.53 80/TCP,5090/TCP 89s +service/scylla-manager-client ClusterIP None 9180/TCP,5090/TCP 89s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/scylla-manager 1/1 1 1 89s +deployment.apps/scylla-manager-controller 2/2 2 2 89s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/scylla-manager-669db64dd 1 1 1 89s +replicaset.apps/scylla-manager-controller-844ccc56c4 2 2 2 89s + + +``` + +Good to go, ready to serve! + +Scylla itself: +```shell +$ kubectl -n scylla get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-us-east-1-us-east-1b-0 2/2 Running 0 5m58s +pod/scylla-us-east-1-us-east-1b-1 2/2 Running 0 4m29s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-client ClusterIP None 9180/TCP,5090/TCP 5m59s +service/scylla-us-east-1-us-east-1b-0 ClusterIP 10.43.149.92 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 5m58s +service/scylla-us-east-1-us-east-1b-1 ClusterIP 10.43.49.0 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 4m29s + +NAME READY AGE +statefulset.apps/scylla-us-east-1-us-east-1b 2/2 5m59s +``` + +Two running nodes, exactly what we were asking for. + +## Monitoring + +To spin up a Prometheus monitoring refer to [monitoring guide](monitoring.md). + +Helm charts can create ServiceMonitors needed to observe Scylla Managger and Scylla. +Both of these Helm Charts allows to specify whether you want to create a ServiceMonitor: +```yaml +serviceMonitor: + create: false +``` + +Change `create` to `true` and update your current deployment using: +```shell +helm upgrade --install scylla --namespace scylla scylla/scylla -f examples/helm/values.cluster.yaml +``` + +Helm should notice the difference, install the ServiceMonitor, and then Prometheous will be able to scrape metrics. + +## Cleanup + +To remove these applications you can simply uninstall them using Helm CLI: +```shell +helm uninstall scylla -n scylla +helm uninstall scylla-manager -n scylla-manager +helm uninstall scylla-operator -n scylla-operator +``` diff --git a/v1.10/_sources/index.rst.txt b/v1.10/_sources/index.rst.txt new file mode 100644 index 00000000000..9c671aaad98 --- /dev/null +++ b/v1.10/_sources/index.rst.txt @@ -0,0 +1,62 @@ +============================= +Scylla Operator Documentation +============================= + +.. toctree:: + :hidden: + :maxdepth: 1 + + generic + eks + gke + helm + manager + monitoring + migration + nodeoperations/index + performance + upgrade + releases + known-issues + scylla-cluster-crd + contributing + +Scylla Operator is an open source project which helps users of Scylla Open Source and Scylla Enterprise run Scylla on Kubernetes (K8s) +The Scylla operator manages Scylla clusters deployed to Kubernetes and automates tasks related to operating a Scylla cluster, like installation, out and downscale, rolling upgrades. + +.. image:: logo.png + :width: 200pt + +For the latest status of the project, and reports issue, see the Github Project. Also check out the K8s Operator lesson on Scylla University. + +scylla-operator is a Kubernetes Operator for managing Scylla clusters. + +Currently it supports: + +* Deploying multi-zone clusters +* Scaling up or adding new racks +* Scaling down +* Monitoring with Prometheus and Grafana +* Integration with `Scylla Manager `_ +* Dead node replacement +* Version Upgrade +* Backup +* Repairs +* Autohealing +* Monitoring with Prometheus and Grafana + +**Choose a topic to begin**: + +* :doc:`Deploying Scylla on a Kubernetes Cluster ` +* :doc:`Deploying Scylla on EKS ` +* :doc:`Deploying Scylla on GKE ` +* :doc:`Deploying Scylla Manager on a Kubernetes Cluster ` +* :doc:`Deploying Scylla stack using Helm Charts ` +* :doc:`Setting up Monitoring using Prometheus and Grafana ` +* :doc:`Node operations ` +* :doc:`Performance tuning [Experimental] ` +* :doc:`Upgrade procedures ` +* :doc:`Releases ` +* :doc:`Known issues ` +* :doc:`Scylla Cluster Custom Resource Definition (CRD) ` +* :doc:`Contributing to the Scylla Operator Project ` diff --git a/v1.10/_sources/known-issues.md.txt b/v1.10/_sources/known-issues.md.txt new file mode 100644 index 00000000000..1af3a7bfdd1 --- /dev/null +++ b/v1.10/_sources/known-issues.md.txt @@ -0,0 +1,14 @@ +# Known issues + +### Scylla Manager does not boot up on Minikube + +If your Scylla Manager is failing to apply 8th migration (008_*), then apply fix for [TRUNCATE queries](#truncate-queries-does-not-work-on-minikube). + +### TRUNCATE queries does not work on Minikube + +The `TRUNCATE` queries requires [hairpinning](https://en.wikipedia.org/wiki/Hairpinning) to be enabled. On minikube this is disabled by default. + +To fix it execute the following command: +``` +minikube ssh sudo ip link set docker0 promisc on +``` diff --git a/v1.10/_sources/manager.md.txt b/v1.10/_sources/manager.md.txt new file mode 100644 index 00000000000..10ee6839cbd --- /dev/null +++ b/v1.10/_sources/manager.md.txt @@ -0,0 +1,258 @@ +# Deploying Scylla Manager on a Kubernetes Cluster + +Scylla Manager is a product for database operations automation, +it can schedule tasks such as repairs and backups. +Scylla Manager can manage multiple Scylla clusters and run cluster-wide tasks +in a controlled and predictable way. + +Scylla Manager is available for Scylla Enterprise customers and Scylla Open Source users. +With Scylla Open Source, Scylla Manager is limited to 5 nodes. +See the Scylla Manager [Proprietary Software License Agreement](https://www.scylladb.com/scylla-manager-software-license-agreement/) for details. + +## Prerequisites + +* Kubernetes cluster +* Scylla Operator - see [generic guide](generic.md) + +## Architecture + +Scylla Manager in K8s consist of: +- Dedicated Scylla Cluster + + Scylla Manager persists its state to a Scylla cluster. +Additional small single node cluster is spawned in the Manager namespace. + +- Scylla Manager Controller + + Main mission of Controller is to watch changes of Scylla Clusters, and synchronize three states. + 1. What user wants - task definition in CRD. + 2. What Controller registered - Task name to Task ID mapping - CRD status. + 3. Scylla Manager task listing - internal state of Scylla Manager. + + When Scylla Cluster CRD is being deployed Controller will register it in Scylla Manager once cluster reaches desired node count. +Once Cluster is fully up and running it will schedule all tasks defined in Cluster CRD. +Controller also supports task updates and unscheduling. + +- Scylla Manager + + Regular Scylla Manager, the same used in cloud and bare metal deployments. + + + +## Deploy Scylla Manager + +Deploy the Scylla Manager using the following commands: + +```console +kubectl apply -f examples/common/manager.yaml +``` + +This will install the Scylla Manager in the `scylla-manager` namespace. +You can check if the Scylla Manager is up and running with: + +```console +kubectl -n scylla-manager get pods +NAME READY STATUS RESTARTS AGE +scylla-manager-cluster-manager-dc-manager-rack-0 2/2 Running 0 37m +scylla-manager-controller-0 1/1 Running 0 28m +scylla-manager-scylla-manager-7bd9f968b9-w25jw 1/1 Running 0 37m +``` + +As you can see there are three pods: +* `scylla-manager-cluster-manager-dc-manager-rack-0` - is a single node Scylla cluster. +* `scylla-manager-controller-0` - Scylla Manager Controller. +* `scylla-manager-scylla-manager-7bd9f968b9-w25jw` - Scylla Manager. + +To see if Scylla Manager is fully up and running we can check their logs. +To do this, execute following command: + + ```console +kubectl -n scylla-manager logs scylla-manager-controller-0 +``` + +The output should be something like: +```console +{"L":"INFO","T":"2020-09-23T11:25:27.882Z","M":"Scylla Manager Controller started","version":"","build_date":"","commit":"","built_by":"","go_version":"","options":{"Name":"scylla-manager-controller-0","Namespace":"scylla-manager","LogLevel":"debug","ApiAddress":"http://127.0.0.1:5080/api/v1"},"_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"} +{"L":"INFO","T":"2020-09-23T11:25:28.435Z","M":"Registering Components.","_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"} +``` + +To check logs of Scylla Manager itself, use following command: +```console +kubectl -n scylla-manager logs scylla-manager-scylla-manager-7bd9f968b9-w25jw +``` + +The output should be something like: + +```console +{"L":"INFO","T":"2020-09-23T11:26:53.238Z","M":"Scylla Manager Server","version":"2.1.2-0.20200816.76cc4dcc","pid":1,"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Using config","config":{"HTTP":"127.0.0.1:5080","HTTPS":"","TLSCertFile":"/var/lib/scylla-manager/scylla_manager.crt","TLSKeyFile":"/var/lib/scylla-manager/scylla_manager.key","TLSCAFile":"","Prometheus":":56090","PrometheusScrapeInterval":5000000000,"debug":"127.0.0.1:56112","Logger":{"Mode":"stderr","Level":"info","Development":false},"Database":{"Hosts":["scylla-manager-cluster-manager-dc-manager-rack-0.scylla-manager.svc"],"SSL":false,"User":"","Password":"","LocalDC":"","Keyspace":"scylla_manager","MigrateDir":"/etc/scylla-manager/cql","MigrateTimeout":30000000000,"MigrateMaxWaitSchemaAgreement":300000000000,"ReplicationFactor":1,"Timeout":600000000,"TokenAware":true},"SSL":{"CertFile":"","Validate":true,"UserCertFile":"","UserKeyFile":""},"Healthcheck":{"Timeout":250000000,"SSLTimeout":750000000},"Backup":{"DiskSpaceFreeMinPercent":10,"AgeMax":43200000000000},"Repair":{"SegmentsPerRepair":1,"ShardParallelMax":0,"ShardFailedSegmentsMax":100,"PollInterval":200000000,"ErrorBackoff":300000000000,"AgeMax":0,"ShardingIgnoreMsbBits":12}},"config_files":["/mnt/etc/scylla-manager/scylla-manager.yaml"],"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Checking database connectivity...","_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +``` + +If there are no errors in the logs, let's spin a Scylla Cluster. + +## Cluster registration + + +When the Scylla Manager is fully up and running, lets create a regular instance of Scylla cluster. + +See [generic tutorial](generic.md) to spawn your cluster. + +Note: If you already have some Scylla Clusters, after installing Manager they should be +automatically registered in Scylla Manager. + +Once cluster reaches desired node count, cluster status will be updated with ID under which it was registered in Manager. + + ```console +kubectl -n scylla describe Cluster + +[...] +Status: + Manager Id: d1d532cd-49f2-4c97-9263-25126532803b + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.0.0 +``` +You can use this ID to talk to Scylla Manager using `sctool` CLI installed in Scylla Manager Pod. +You can also use Cluster name in `namespace/cluster-name` format. + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list + +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b) +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮ +│ Task │ Arguments │ Next run │ Status │ +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤ +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b │ │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE │ +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd │ │ 23 Sep 20 14:29:57 CEST (+1m) │ NEW │ +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯ + +``` + +Scylla Manager by default registers recurring healhcheck tasks for Agent and for each of the enabled frontends (CQL, Alternator). + +In this task listing we can see CQL and REST healthchecks. + +## Task scheduling + +You can either define tasks prior Cluster creation, or for existing Cluster. +Let's edit already running cluster definition to add repair and backup task. +```console +kubectl -n scylla edit Cluster simple-cluster +``` + +Add following task definition to Cluster spec: +``` + repairs: + - name: "users repair" + keyspace: ["users"] + interval: "1d" + backup: + - name: "weekly backup" + location: ["s3:cluster-backups"] + retention: 3 + interval: "7d" + - name: "daily backup" + location: ["s3:cluster-backups"] + retention: 7 + interval: "1d" +``` + +For full task definition configuration consult [Scylla Cluster CRD](scylla-cluster-crd.md). + +**Note**: Scylla Manager Agent must have access to above bucket prior the update in order to schedule backup task. +Consult Scylla Manager documentation for details on how to set it up. + +Scylla Manager Controller will spot this change and will schedule tasks in Scylla Manager. + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list + +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b) +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮ +│ Task │ Arguments │ Next run │ Status │ +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤ +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b │ │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE │ +│ backup/275aae7f-c436-4fc8-bcec-479e65fb8372 │ -L s3:cluster-backups --retention 3 │ 23 Sep 20 14:28:58 CEST (+7d) │ NEW │ +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd │ │ 23 Sep 20 14:29:57 CEST (+1m) │ NEW │ +│ repair/d4946360-c29d-4bb4-8b9d-619ada495c2a │ │ 23 Sep 20 14:38:42 CEST │ NEW │ +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯ + +``` + +As you can see, we have two new tasks, weekly recurring backup, and one repair which should start shortly. + +To check progress of run you can use following command: + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task progress --cluster d1d532cd-49f2-4c97-9263-25126532803b repair/d4946360-c29d-4bb4-8b9d-619ada495c2a +Status: RUNNING +Start time: 23 Sep 20 14:38:42 UTC +Duration: 13s +Progress: 2.69% +Datacenters: + - us-east-1 ++--------------------+-------+ +| system_auth | 8.06% | +| system_distributed | 0.00% | +| system_traces | 0.00% | ++--------------------+-------+ + +``` +Other tasks can be also tracked using the same command, but using different task ID. +Task IDs are present in Cluster Status as well as in task listing. + +## Clean Up + +To clean up all resources associated with Scylla Manager, you can run the commands below. + +**NOTE:** this will destroy your Scylla Manager database and delete all of its associated data. + +```console +kubectl delete -f examples/common/manager.yaml +``` + +## Troubleshooting + +**Manager is not running** + +If the Scylla Manager does not come up, the first step would be to examine the Manager and Controller logs: + +```console +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-controller +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-scylla-manager-7bd9f968b9-w25jw +``` + + +**My task wasn't scheduled** + +If your task wasn't scheduled, Cluster status will be updated with error messages for each failed task. +You can also consult Scylla Manager logs. + +Example: + +Following status describes error when backup task cannot be scheduled, due to lack of access to bucket: +```console +Status: + Backups: + Error: create backup target: location is not accessible: 10.100.16.62: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.100.16.62 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.107.193.33: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.107.193.33 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.109.197.60: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.109.197.60 and run "scylla-manager-agent check-location -L s3:manager-test --debug" + Id: 00000000-0000-0000-0000-000000000000 + Interval: 0 + Location: + s3:manager-test + Name: adhoc backup + Num Retries: 3 + Retention: 3 + Start Date: now + Manager Id: 2b9dbe8c-9daa-4703-a66d-c29f63a917c8 + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.0.0 +``` + +Because Controller is infinitely retrying to schedule each defined task, once permission issues will be resolved, +task should appear in task listing and Cluster status. \ No newline at end of file diff --git a/v1.10/_sources/migration.md.txt b/v1.10/_sources/migration.md.txt new file mode 100644 index 00000000000..cdd7a7e8522 --- /dev/null +++ b/v1.10/_sources/migration.md.txt @@ -0,0 +1,146 @@ +## Version migrations + + +### `v0.3.0` -> `v1.0.0` migration + +`v0.3.0` used a very common name as a CRD kind (`Cluster`). In `v1.0.0` this issue was solved by using less common kind +which is easier to disambiguate (`ScyllaCluster`). +***This change is backward incompatible, which means manual migration is needed.*** + +This procedure involves having two CRDs registered at the same time. We will detach Scylla Pods +from Scylla Operator for a short period to ensure that nothing is garbage collected when Scylla Operator is upgraded. +Compared to the [upgrade guide](upgrade.md) where full deletion is requested, this procedure shouldn't cause downtimes. +Although detaching resources from their controller is considered hacky. This means that you shouldn't run procedure +out of the box on production. Make sure this procedure works well multiple times on your staging environment first. + +***Read the whole procedure and make sure you understand what is going on before executing any of the commands!*** + +In case of any issues or questions regarding this procedure, you're welcomed on our [Scylla Users Slack](http://slack.scylladb.com/) +on #kubernetes channel. + +### Procedure + +1. Execute this whole procedure for each cluster sequentially. To get a list of existing clusters execute the following + ``` + kubectl -n scylla get cluster.scylla.scylladb.com + + NAME AGE + simple-cluster 30m + ``` + All below commands will use `scylla` namespace and `simple-cluster` as a cluster name. +1. Make sure you're using v1.0.0 tag: + ``` + git checkout v1.0.0 + ``` +1. Upgrade your `cert-manager` to `v1.0.0`. If you installed it from a static file from this repo, simply execute the following: + ``` + kubectl apply -f examples/common/cert-manager.yaml + ``` + If your `cert-manager` was installed in another way, follow official instructions on `cert-manager` website. +1. `examples/common/operator.yaml` file contains multiple resources. Extract **only** `CustomResourceDefinition` to separate file. +1. Install v1.0.0 CRD definition from file created in the previous step: + ``` + kubectl apply -f examples/common/crd.yaml + ``` +1. Save your existing `simple-cluster` Cluster definition to a file: + ``` + kubectl -n scylla get cluster.scylla.scylladb.com simple-cluster -o yaml > existing-cluster.yaml + ``` +1. Migrate `Kind` and `ApiVersion` to new values using: + ``` + sed -i 's/scylla.scylladb.com\/v1alpha1/scylla.scylladb.com\/v1/g' existing-cluster.yaml + sed -i 's/kind: Cluster/kind: ScyllaCluster/g' existing-cluster.yaml + ``` +1. Install migrated CRD instance + ``` + kubectl apply -f existing-cluster.yaml + ``` + At this point, we should have two CRDs describing your Scylla cluster, although the new one is not controlled by the Operator. +1. Get UUID of newly created ScyllaCluster resource: + ``` + kubectl -n scylla get ScyllaCluster simple-cluster --template="{{ .metadata.uid }}" + + 12a3678d-8511-4c9c-8a48-fa78d3992694 + ``` + Save output UUID somewhere, it will be referred as `` in commands below. + + ***Depending on your shell, you might get additional '%' sign at the end of UUID, make sure to remove it!*** + +1. Upgrade ClusterRole attached to each of the Scylla nodes to grant them permission to lookup Scylla clusters: + ``` + kubectl patch ClusterRole simple-cluster-member --type "json" -p '[{"op":"add","path":"/rules/-","value":{"apiGroups":["scylla.scylladb.com"],"resources":["scyllaclusters"],"verbs":["get"]}}]' + ``` + Amend role name according to your cluster name, it should look like `-member`. +1. Get a list of all Services associated with your cluster. First get list of all services: + ``` + kubectl -n scylla get svc -l "scylla/cluster=simple-cluster" + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 109m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.23.96 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 109m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.66.22 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 108m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.246.25 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 106m + + ``` +1. For each service, change its `ownerReference` to point to new CRD instance: + ``` + kubectl -n scylla patch svc --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":""}]' + ``` + Replace `` with Service name, and `` with saved UUID from one of the previous steps. +1. Get a list of all Services again to see if none was deleted. Check also "Age" column, it shouldn't be lower than previous result. + ``` + kubectl -n scylla get svc -l "scylla/cluster=simple-cluster" + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 110m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.23.96 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 110m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.66.22 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 109m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.246.25 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 107m + + ``` +1. Get a list of StatefulSets associated with your cluster: + ``` + kubectl -n scylla get sts -l "scylla/cluster=simple-cluster" + + NAME READY AGE + simple-cluster-us-east-1-us-east-1a 3/3 104m + ``` +1. For each StatefulSet from previous step, change its `ownerReference` to point to new CRD instance. + + ``` + kubectl -n scylla patch sts --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":""}]' + ``` + Replace `` with StatefulSet name, and `` with saved UUID from one of the previous steps. + +1. Now when all k8s resources bound to Scylla are attached to new CRD, we can remove 0.3.0 Operator and old CRD definition. + Checkout `v0.3.0` version, and remove Scylla Operator, and old CRD: + ``` + git checkout v0.3.0 + kubectl delete -f examples/generic/operator.yaml + ``` +1. Checkout `v1.0.0`, and install upgraded Scylla Operator: + ``` + git checkout v1.0.0 + kubectl apply -f examples/common/operator.yaml + ``` +1. Wait until Scylla Operator boots up: + ``` + kubectl -n scylla-operator-system wait --for=condition=ready pod --all --timeout=600s + ``` +1. Get a list of StatefulSets associated with your cluster: + ``` + kubectl -n scylla get sts -l "scylla/cluster=simple-cluster" + + NAME READY AGE + simple-cluster-us-east-1-us-east-1a 3/3 104m +1. For each StatefulSet from previous step, change its sidecar container image to `v1.0.0`, and wait until change will be propagated. This step will initiate a rolling restart of pods one by one. + ``` + kubectl -n scylla patch sts --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/initContainers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]' + kubectl -n scylla rollout status sts + ``` + Replace `` with StatefulSet name. +1. If you're using Scylla Manager, bump Scylla Manager Controller image to `v1.0.0` + ``` + kubectl -n scylla-manager-system patch sts scylla-manager-controller --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]' + ``` +1. Your Scylla cluster is now migrated to `v1.0.0`. diff --git a/v1.10/_sources/monitoring.md.txt b/v1.10/_sources/monitoring.md.txt new file mode 100644 index 00000000000..9f2651c5737 --- /dev/null +++ b/v1.10/_sources/monitoring.md.txt @@ -0,0 +1,180 @@ +# Monitoring + +Scylla Operator 1.8 introduced a new API resource `ScyllaDBMonitoring`, allowing users to deploy a managed monitoring +setup for their Scylla Clusters. + +```yaml +apiVersion: scylla.scylladb.com/v1alpha1 +kind: ScyllaDBMonitoring +metadata: + name: example +spec: + type: Platform + endpointsSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla-operator.scylladb.com/scylla-service-type: identity + scylla/cluster: replace-with-your-scyllacluster-name + components: + prometheus: + storage: + volumeClaimTemplate: + spec: + resources: + requests: + storage: 1Gi + grafana: + exposeOptions: + webInterface: + ingress: + ingressClassName: haproxy + dnsDomains: + - test-grafana.test.svc.cluster.local + annotations: + haproxy-ingress.github.io/ssl-passthrough: "true" +``` + +For details, refer to the below command: +```console +$ kubectl explain scylladbmonitorings.scylla.scylladb.com/v1alpha1 +``` + +## Deploy managed monitoring + +**Note**: as of v1.8, ScyllaDBMonitoring is experimental. The API is currently in version v1alpha1 and may change in future versions. + +### Requirements + +Before you can set up your ScyllaDB monitoring, you need Scylla Operator already installed in your Kubernetes cluster. +For more information on how to deploy Scylla Operator, see: +* [Deploying Scylla on a Kubernetes Cluster](generic.md) +* [Deploying Scylla stack using Helm Charts](helm.md) + +The above example of the monitoring setup also makes use of HAProxy Ingress and Prometheus Operator. +You can deploy them in your Kubernetes cluster using the provided third party examples. If you already have them deployed +in your cluster, you can skip the below steps. + +#### Deploy Prometheus Operator +Deploy Prometheus Operator using kubectl: +```console +$ kubectl -n prometheus-operator apply --server-side -f ./examples/third-party/prometheus-operator +``` + +##### Wait for Prometheus Operator to roll out +```console +$ kubectl -n prometheus-operator rollout status --timeout=5m deployments.apps/prometheus-operator +deployment "prometheus-operator" successfully rolled out +``` + +#### Deploy HAProxy Ingress +Deploy HAProxy Ingress using kubectl: +```console +$ kubectl -n haproxy-ingress apply --server-side -f ./examples/third-party/haproxy-ingress +``` + +##### Wait for HAProxy Ingress to roll out +```console +$ kubectl -n haproxy-ingress rollout status --timeout=5m deployments.apps/haproxy-ingress +deployment "haproxy-ingress" successfully rolled out +``` + +### Deploy ScyllaDBMonitoring + +First, update the `endpointsSelector` in `examples/monitoring/v1alpha1/scylladbmonitoring.yaml` with a label +matching your ScyllaCluster instance name. + +Deploy the monitoring setup using kubectl: +```console +$ kubectl -n scylla apply --server-side -f ./examples/monitoring/v1alpha1/scylladbmonitoring.yaml +``` + +Scylla Operator will notice the new ScyllaDBMonitoring object, and it will reconcile all necessary resources. + +#### Wait for ScyllaDBMonitoring to roll out +```console +$ kubectl wait --for='condition=Progressing=False' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met + +$ kubectl wait --for='condition=Degraded=False' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met + +$ kubectl wait --for='condition=Available=True' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met +``` + +#### Wait for Prometheus to roll out +```console +$ kubectl rollout status --timeout=5m statefulset.apps/prometheus-example +statefulset rolling update complete 1 pods at revision prometheus-example-65b89d55bb... +``` + +#### Wait for Grafana to roll out +```console +$ kubectl rollout status --timeout=5m deployments.apps/example-grafana +deployment "example-grafana" successfully rolled out +``` + +### Accessing Grafana + +For accessing Grafana service from outside the Kubernetes cluster we recommend using an Ingress, although there are many other ways to do so. +When using Ingress, what matters is to direct your packets to the ingress controller Service/Pods and have the correct TLS SNI field set by the caller when reaching out to the service, so it is routed properly, and your client can successfully validate the grafana serving certificate. +This is easier when you are using a real DNS domain that resolves to your Ingress controller's IP address but most clients and tools allow setting the SNI field manually. + +### Prerequisites + +To access Grafana, you first need to collect the serving CA and the credentials. + +```console +$ GRAFANA_SERVING_CERT="$( kubectl -n scylla get secret/example-grafana-serving-ca --template '{{ index .data "tls.crt" }}' | base64 -d )" +$ GRAFANA_USER="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "username" }}' | base64 -d )" +$ GRAFANA_PASSWORD="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "password" }}' | base64 -d )" +``` + +### Connecting through Ingress using a resolvable domain + +In production clusters, the Ingress controller and appropriate DNS records should be set up already. Often there is already a generic wildcard record like `*.app.mydomain` pointing to the Ingress controller's external IP. For custom service domains, it is usually a CNAME pointing to the Ingress controller's A record. + +Note: The ScyllaDBMonitoring example creates an Ingress object with `test-grafana.test.svc.cluster.local` DNS domain that you should adjust to your domain. Below examples use `example-grafana.apps.mydomain`. + +Note: To test a resolvable domain from your machine without creating DNS records, you can adjust `/etc/hosts` or similar. + +```console +$ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://example-grafana.apps.mydomain" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}" +200 +``` + +### Connecting through Ingress using an unresolvable domain + +To connect to an Ingress without a resolvable domain you first need to find out your Ingress controller's IP that can be resolved externally. Again, there are many ways to do so beyond the below examples. + +Unless stated otherwise, we assume your Ingress is running on port 443. + +```console +$ INGRESS_PORT=443 +``` + +#### Variants + +##### Ingress ExternalIP + +When you are running in a real cluster there is usually a cloud LoadBalancer or a bare metal alternative providing you with an externally reachable IP address. + +```console +$ INGRESS_IP="$( kubectl -n=haproxy-ingress get service/haproxy-ingress --template='{{ ( index .status.loadBalancer.ingress 0 ).ip }}' )" +``` + +##### Ingress NodePort + +NodePort is slightly less convenient, but it's available in development clusters as well. + +```console +$ INGRESS_IP="$( kubectl get nodes --template='{{ $internal_ip := "" }}{{ $external_ip := "" }}{{ range ( index .items 0 ).status.addresses }}{{ if eq .type "InternalIP" }}{{ $internal_ip = .address }}{{ else if eq .type "ExternalIP" }}{{ $external_ip = .address }}{{ end }}{{ end }}{{ if $external_ip }}{{ $external_ip }}{{ else }}{{ $internal_ip }}{{ end }}' )" +$ INGRESS_PORT="$( kubectl -n=haproxy-ingress get services/haproxy-ingress --template='{{ range .spec.ports }}{{ if eq .port 443 }}{{ .nodePort }}{{ end }}{{ end }}' )" +``` + +##### Connection + +```console +$ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://test-grafana.test.svc.cluster.local:${INGRESS_PORT}" --resolve "test-grafana.test.svc.cluster.local:${INGRESS_PORT}:${INGRESS_IP}" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}" +200 +``` diff --git a/v1.10/_sources/nodeoperations/automatic-cleanup.md.txt b/v1.10/_sources/nodeoperations/automatic-cleanup.md.txt new file mode 100644 index 00000000000..5e0535cca97 --- /dev/null +++ b/v1.10/_sources/nodeoperations/automatic-cleanup.md.txt @@ -0,0 +1,6 @@ +# Automatic cleanup and replacement in case when k8s node is lost + +In case when your k8s cluster loses one of the nodes due to incident or explicit removal, Scylla Pods may become unschedulable due to PVC node affinity. + +When `automaticOrphanedNodeCleanup` flag is enabled in your ScyllaCluster, Scylla Operator will perform automatic +node replacement of a Pod which lost his bound resources. diff --git a/v1.10/_sources/nodeoperations/index.rst.txt b/v1.10/_sources/nodeoperations/index.rst.txt new file mode 100644 index 00000000000..c04919e5d13 --- /dev/null +++ b/v1.10/_sources/nodeoperations/index.rst.txt @@ -0,0 +1,22 @@ +====================================== +Node operations using Scylla Operator +====================================== + +.. toctree:: + :hidden: + :maxdepth: 2 + + scylla-upgrade + replace-node + automatic-cleanup + maintenance-mode + restore + + +Choose a topic: + +* :doc:`Scylla version upgrade ` +* :doc:`Replace Scylla node ` +* :doc:`Automatic cleanup and replacement when k8s node is lost ` +* :doc:`Maintenance mode ` +* :doc:`Restore from backup ` \ No newline at end of file diff --git a/v1.10/_sources/nodeoperations/maintenance-mode.md.txt b/v1.10/_sources/nodeoperations/maintenance-mode.md.txt new file mode 100644 index 00000000000..c976ecc2b87 --- /dev/null +++ b/v1.10/_sources/nodeoperations/maintenance-mode.md.txt @@ -0,0 +1,19 @@ +# Maintenance mode + +When maintenance mode is enabled, readiness probe of Scylla Pod will always return failure and liveness probe will always succeed. This causes that Pod under maintenance +is being removed from K8s Load Balancer and DNS registry but Pod itself stays alive. + +This allows the Scylla Operator to interact with Scylla and Scylla dependencies inside the Pod. +For example user may turn off Scylla process, do something with the filesystem and bring the process back again. + +To enable maintenance mode add `scylla/node-maintenance` label to service in front of Scylla Pod. + +```bash +kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance="" +``` + +To disable, simply remove this label from service. + +```bash +kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance- +``` diff --git a/v1.10/_sources/nodeoperations/replace-node.md.txt b/v1.10/_sources/nodeoperations/replace-node.md.txt new file mode 100644 index 00000000000..3e6a8c7f024 --- /dev/null +++ b/v1.10/_sources/nodeoperations/replace-node.md.txt @@ -0,0 +1,74 @@ +# Replacing a Scylla node + +## Replacing a dead node +In the case of a host failure, it may not be possible to bring back the node to life. + +Replace dead node operation will cause the other nodes in the cluster to stream data to the node that was replaced. +This operation can take some time (depending on the data size and network bandwidth). + +_This procedure is for replacing one dead node. To replace more than one dead node, run the full procedure to completion one node at a time_ + +**Procedure** + +1. Verify the status of the node using `nodetool status` command, the node with status DN is down and need to be replaced + ```bash + kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status + Datacenter: us-east-1 + ===================== + Status=Up/Down + |/ State=Normal/Leaving/Joining/Moving + -- Address Load Tokens Owns Host ID Rack + UN 10.43.125.110 74.63 KB 256 ? 8ebd6114-969c-44af-a978-87a4a6c65c3e us-east-1a + UN 10.43.231.189 91.03 KB 256 ? 35d0cb19-35ef-482b-92a4-b63eee4527e5 us-east-1a + DN 10.43.43.51 74.77 KB 256 ? 1ffa7a82-c41c-4706-8f5f-4d45a39c7003 us-east-1a + ``` +1. Identify service which is bound to down node by checking IP address + ```bash + kubectl -n scylla get svc + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 3h12m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.231.189 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h12m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.125.110 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h11m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.43.51 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h5m + ``` +1. Drain node which we would like to replace using. **This command may delete your data from local disks attached to given node!** + ```bash + kubectl drain gke-scylla-demo-default-pool-b4b390a1-6j12 --ignore-daemonsets --delete-local-data + ``` + + Pod which will be replaced should enter the `Pending` state + ```bash + kubectl -n scylla get pods + NAME READY STATUS RESTARTS AGE + simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 3h21m + simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 3h19m + simple-cluster-us-east-1-us-east-1a-2 0/2 Pending 0 8m14s + ``` +1. To being node replacing, add `scylla/replace=""` label to service bound to pod we are replacing. + ```bash + kubectl -n scylla label svc simple-cluster-us-east-1-us-east-1a-2 scylla/replace="" + ``` + Your failed Pod should be recreated on available k8s node + ```bash + kubectl -n scylla get pods + NAME READY STATUS RESTARTS AGE + simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 3h27m + simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 3h25m + simple-cluster-us-east-1-us-east-1a-2 1/2 Running 0 9s + ``` + Because other nodes in cluster must stream data to new node this operation might take some time depending on how much data your cluster stores. + After bootstraping is over, your new Pod should be ready to go. + Old one shouldn't be no longer visible in `nodetool status` + ```bash + kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status + Datacenter: us-east-1 + ===================== + Status=Up/Down + |/ State=Normal/Leaving/Joining/Moving + -- Address Load Tokens Owns Host ID Rack + UN 10.43.125.110 74.62 KB 256 ? 8ebd6114-969c-44af-a978-87a4a6c65c3e us-east-1a + UN 10.43.231.189 91.03 KB 256 ? 35d0cb19-35ef-482b-92a4-b63eee4527e5 us-east-1a + UN 10.43.191.172 74.77 KB 256 ? 1ffa7a82-c41c-4706-8f5f-4d45a39c7003 us-east-1a + ``` +1. Run the repair on the cluster to make sure that the data is synced with the other nodes in the cluster. + You can use [Scylla Manager](../manager.md) to run the repair. diff --git a/v1.10/_sources/nodeoperations/restore.md.txt b/v1.10/_sources/nodeoperations/restore.md.txt new file mode 100644 index 00000000000..b4d85573cff --- /dev/null +++ b/v1.10/_sources/nodeoperations/restore.md.txt @@ -0,0 +1,89 @@ +# Restore from backup + +This procedure will describe how to restore from backup taken using [Scylla Manager](../manager.md) to a fresh **empty** cluster of any size. + +First identify to which snapshot you want to restore. To get list of available snapshot execute following command on Scylla Manager Pod. +```bash +sctool backup list -c --all-clusters -L +``` + +Where: +* `CLUSTER_ID` - is a name of a cluster or ID under which ScyllaCluster was registered. You can find it in ScyllaCluster Status. +* `BACKUP_LOCATION` - is a location where backup is stored. For example, for bucket called `backups` stored in AWS S3, location is `s3:backups`. + +```bash +sctool backup list -c simple-cluster --all-clusters -L s3:backups +Snapshots: + - sm_20201227144037UTC (409MiB) + - sm_20201228145917UTC (434MiB) +Keyspaces: + - users (9 tables) + - system_auth (2 tables) + - system_distributed (3 tables) + - system_schema (13 tables) + - system_traces (5 tables) +``` + +To get the list of files use: + +```bash +sctool backup files -c -L -T +``` + +Where: +* `SNAPSHOT_TAG` - name of snapshot you want to restore. + +Before we start restoring the data, we have to restore the schema. +The first output line is a path to schemas archive, for example: +```bash +s3://backups/backup/schema/cluster/ed63b474-2c05-4f4f-b084-94541dd86e7a/task_287791d9-c257-4850-aef5-7537d6e69d90_tag_sm_20201228145917UTC_schema.tar.gz ./ +``` + +To download this archive you can use AWS CLI tool `aws s3 cp`. + +This archive contains a single CQL file for each keyspace in the backup. +```bash +tar -ztvf task_287791d9-c257-4850-aef5-7537d6e69d90_tag_sm_20201228145917UTC_schema.tar.gz +-rw------- 0/0 12671 2020-12-28 13:17 users.cql +-rw------- 0/0 2216 2020-12-28 13:17 system_auth.cql +-rw------- 0/0 921 2020-12-28 13:17 system_distributed.cql +-rw------- 0/0 12567 2020-12-28 13:17 system_schema.cql +-rw------- 0/0 4113 2020-12-28 13:17 system_traces.cql +``` + +Extract this archive and copy each schema file to one of the cluster Pods by: +```bash +kubectl -n scylla cp users.cql simple-cluster-us-east-1-us-east-1a-0:/tmp/users.cql -c scylla +``` + +To import schema simply execute: +```bash +kubectl -n scylla exec simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -f /tmp/users.cql +``` + +Once the schema is recreated we can proceed to downloading data files. + +First let's save a list of snapshot files to file called `backup_files.out`: + +```bash +kubectl -n scylla-manager exec deployment.apps/scylla-manager-controller -- sctool backup files -c simple-cluster -L s3:backups -T sm_20201228145917UTC > backup_files.out +``` + +We will be using `sstableloader` to restore data. `sstableloader` needs a specific directory structure to work namely: `//` +To create this directory structure and download all the files execute these commands: +```bash +mkdir snapshot +cd snapshot +# Create temporary directory structure. +cat ../backup_files.out | awk '{print $2}' | xargs mkdir -p +# Download snapshot files. +cat ../backup_files.out | xargs -n2 aws s3 cp +``` + +To load data into cluster pass cluster address to `sstableloader` together with path to data files and credentials: +```bash +sstableloader -d 'simple-cluster-us-east-1-us-east-1a-0.scylla.svc,simple-cluster-us-east-1-us-east-1a-1.scylla.svc,simple-cluster-us-east-1-us-east-1a-2.scylla.svc' ./users/data_0 --username scylla --password +``` + +Depending on how big is your data set, this operation may take some time. +Once it finishes, data from the snapshot is restored and you may clean up the host. diff --git a/v1.10/_sources/nodeoperations/scylla-upgrade.md.txt b/v1.10/_sources/nodeoperations/scylla-upgrade.md.txt new file mode 100644 index 00000000000..d39c9666c5e --- /dev/null +++ b/v1.10/_sources/nodeoperations/scylla-upgrade.md.txt @@ -0,0 +1,102 @@ +# Upgrading version of Scylla + +To upgrade Scylla version using Operator user have to modify existing ScyllaCluster definition. + +In this example cluster will be upgraded to version `4.4.5`. +```bash +kubectl -n scylla patch ScyllaCluster simple-cluster -p '{"spec":{"version": "4.4.5"}}' --type=merge +``` + +Operator supports two types of version upgrades: +1. Patch upgrade +1. Generic upgrade + + +**Patch upgrade** + +Patch upgrade is executed when only patch version change is detected according to [semantic versioning format](https://semver.org/). +Procedure simply rolls out a restart of whole cluster and upgrades Scylla container image for each node one by one. + +Example: `4.0.0 -> 4.0.1` + +**Generic upgrade** + +Generic upgrades are executed for the non patch version changes. + +Example: `4.0.0 -> 2020.1.0` or `4.0.0 -> 4.1.0` or even `4.0.0 -> nightly` + +User can observe current state of upgrade in ScyllaCluster status. +```bash +kubectl -n scylla describe ScyllaCluster simple-cluster +[...] +Status: + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.1.9 + Upgrade: + Current Node: simple-cluster-us-east-1-us-east-1a-2 + Current Rack: us-east-1a + Data Snapshot Tag: so_data_20201228135002UTC + From Version: 4.1.9 + State: validate_upgrade + System Snapshot Tag: so_system_20201228135002UTC + To Version: 4.2.2 +``` + +Each upgrade begins with taking a snapshot of `system` and `system_schema` keyspaces on all nodes in parallel. +Name of this snapshot tag is saved in upgrade status under `System Snapshot Tag`. + +Before nodes in rack are upgraded, underlying StatefulSet is changed to use `OnDelete` UpgradeStrategy. +This allows Operator have a full control over when Pod image is changed. + +When a node is being upgraded, [maintenance mode](#maintenance-mode) is enabled, then the node is drained and snapshot of all data keyspaces is taken. +Snapshot tag is saved under `Data Snapshot Tag` and is the same for all nodes during the procedure. +Once everything is set up, maintenance mode is disabled and Scylla Pod is deleted. Underlying StatefulSet will bring up a new +Pod with upgraded version. +Once Pod will become ready, data snapshot from this particular node is removed, and Operator moves to next node. + +Once every rack is upgraded, system snapshot is removed from all nodes in parallel and previous StatefulSet UpgradeStrategy is restored. +At this point, all your nodes should be already in desired version. + +Current state of upgrade can be traced using `Current Node`, `Current Rack` and `State` status fields. +* `Current Node` shows which node is being upgraded. +* `Current Rack` displays which rack is being upgraded. +* `State` contain information at which stage upgrade is. + +`State` can have following values: +* `begin_upgrade` - upgrade is starting +* `check_schema_agreement` - Operator waits until all nodes reach schema agreement. It waits for it for 1 minute, prints an error log message and check is retried. +* `create_system_backup` - system keyspaces snapshot is being taken +* `find_next_rack` - Operator finds out which rack must be upgraded next, decision is saved in `Current Rack` +* `upgrade_image_in_pod_spec` - Image and UpgradeStrategy is upgraded in underlying StatefulSet +* `find_next_node` - Operator finds out which node must be upgraded next, decision is saved in `Current Node` +* `enable_maintenance_mode` - maintenance mode is being enabled +* `drain_node` - node is being drained +* `backup_data` - snapshot of data keyspaces is being taken +* `disable_maintenance_mode` - maintenance mode is being disabled +* `delete_pod` - Scylla Pod is being deleted +* `validate_upgrade` - Operator validates if new pod enters Ready state and if Scylla version is upgraded +* `clear_data_backup` - snapshot of data keyspaces is being removed +* `clear_system_backup` - snapshot of system keyspaces is being removed +* `restore_upgrade_strategy` - restore UpgradeStrategy in underlying StatefulSet +* `finish_upgrade` - upgrade cleanup + +**Recovering from upgrade failure** + +Upgrade may get stuck on `validate_upgrade` stage. This happens when Scylla Pod refuses to properly boot up. + +To continue with upgrade, first turn off operator by scaling Operator replicas to zero: +```bash +kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=0 +``` +Then user have to manually resolve issue with Scylla by checking what is the root cause of a failure in Scylla container logs. +If needed data and system keyspaces SSTable snapshots are available on the node. You can check ScyllaCluster status for their names. + +Once issue is resolved and Scylla Pod is up and running (Pod is in Ready state), scale Operator back to two replicas: +```bash +kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=2 +``` + +Operator should continue upgrade process from where it left off. diff --git a/v1.10/_sources/performance.md.txt b/v1.10/_sources/performance.md.txt new file mode 100644 index 00000000000..4b0bbd96781 --- /dev/null +++ b/v1.10/_sources/performance.md.txt @@ -0,0 +1,95 @@ +# Performance tuning + +Scylla Operator 1.6 introduces a new experimental feature allowing users to optimize Kubernetes nodes. + +## Node tuning + +Starting from Operator 1.6, a new CRD called NodeConfig is available, allowing users to target Nodes which should be tuned. +When a Node is supposed to be optimized, the Scylla Operator creates a DaemonSet covering these Nodes. +Nodes matching the provided placement conditions will be subject to tuning. + +Below example NodeConfig tunes nodes having `scylla.scylladb.com/node-type=scylla` label: +``` +apiVersion: scylla.scylladb.com/v1alpha1 +kind: NodeConfig +metadata: + name: cluster +spec: + placement: + nodeSelector: + scylla.scylladb.com/node-type: scylla +``` +For more details about new CRD use: +``` +kubectl explain nodeconfigs.scylla.scylladb.com/v1alpha1 +``` + +For all optimizations we use a Python script available in the Scylla image called perftune. +Perftune executes the performance optmizations like tuning the kernel, network, disk devices, spreading IRQs across CPUs and more. + +Tuning consists of two separate optimizations: common node tuning, and tuning based on Scylla Pods and their resource assignment. +Node tuning is executed immediately. Pod tuning is executed when Scylla Pod lands on the same Node. + +Scylla works most efficently when it's pinned to CPU and not interrupted. +One of the most common causes of context-switching are network interrupts. Packets coming to a node need to be processed, +and this requires CPU shares. + +On K8s we always have at least a couple of processes running on the node: kubelet, kubernetes provider applications, daemons etc. +These processes require CPU shares, so we cannot dedicate entire node processing power to Scylla, we need to leave space for others. +We take advantage of it, and we pin IRQs to CPUs not used by any Scylla Pods exclusively. + +Tuning resources are created in a special namespace called `scylla-operator-node-tuning`. + +The tuning is applied only to pods with `Guaranteed` QoS class. Please double check your ScyllaCluster resource specification +to see if it meets all conditions. + +## Kubernetes tuning + +By default, the kubelet uses the CFS quota to enforce pod CPU limits. +When the node runs many CPU-bound pods, the workload can move around different CPU cores depending on whether the pod +is throttled and which CPU cores are available. +However, kubelet may be configured to assign CPUs exclusively, by setting the CPU manager policy to static. + +Setting up kubelet configuration is provider specific. Please check the docs for your distribution or talk to your +provider. + +Only pods within the [Guaranteed QoS class](https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed)) can take advantage of this option. +When such pod lands on a Node, kubelet will pin them to specific CPUs, and those won't be part of the shared pool. + +In our case there are two requirements each ScyllaCluster must fulfill to receive a Guaranteed QoS class: +* resource request and limits must be equal or only limits have to be provided +* agentResources must be provided and their requests and limits must be equal, or only limits have to be provided + +An example of such a ScyllaCluster that receives a Guaranteed QoS class is below: + +``` +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: guaranteed-cluster + namespace: scylla +spec: + version: 4.5.1 + agentVersion: 2.5.2 + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 3 + storage: + capacity: 500Gi + agentResources: + requests: + cpu: 1 + memory: 1G + limits: + cpu: 1 + memory: 1G + resources: + requests: + cpu: 4 + memory: 16G + limits: + cpu: 4 + memory: 16G +``` \ No newline at end of file diff --git a/v1.10/_sources/releases.md.txt b/v1.10/_sources/releases.md.txt new file mode 100644 index 00000000000..afb5c8e91d9 --- /dev/null +++ b/v1.10/_sources/releases.md.txt @@ -0,0 +1,58 @@ +# Releases + +## Schedule +We are aiming to ship a new release approximately every 6 weeks. The following release schedule is only advisory, there are no commitments made to hitting these dates. + +| Release | Code freeze | General availability | +|:-------:|:-----------:|:--------------------:| +| 1.10 | 2022-08-08 | 2021-08-15 | + +## Supported releases +We support the latest 2 releases of the operator to give everyone time to upgrade. + +| Release | General availability | Support ends | +|:-------:|:--------------------:|:---------------:| +| 1.9 | 2023-07-04 | Release of 1.11 | +| 1.8 | 2023-01-25 | Release of 1.10 | +| 1.7 | 2022-01-27 | 2023-07-04 | +| 1.6 | 2021-12-03 | 2023-01-25 | +| 1.5 | 2021-09-16 | 2022-01-27 | +| 1.4 | 2021-08-10 | 2021-12-03 | +| 1.3 | 2021-06-17 | 2021-09-16 | +| 1.2 | 2021-05-06 | 2021-08-10 | +| 1.1 | 2021-03-22 | 2021-06-17 | +| 1.0 | 2021-01-21 | 2021-05-06 | + +### Backport policy +Usually, only important bug fixes are eligible for being backported. +This may depend on the situation and assessment of the maintainers. + +## CI/CD +We use [GitHub actions](https://github.com/scylladb/scylla-operator/actions/workflows/go.yaml?query=branch%3Amaster+event%3Apush) for our CI/CD. Every merge to a supported branch, or a creation of a tag will automatically trigger a job to build, test and publish the container image and other artifacts like helm charts. Before we publish any image, it must pass the e2e suite. + +### Automated promotions + +| Git reference | Type | Container image | +| :----------------: | :----: | :--------------------------------------------------: | +| **master** | branch | docker.io/scylladb/scylla-operator:**latest** | +| **vX.Y** | branch | docker.io/scylladb/scylla-operator:**X.Y** | +| **vX.Y.Z** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z** | +| **vX.Y.Z-alpha.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-alpha.N** | +| **vX.Y.Z-beta.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-beta.N** | +| **vX.Y.Z-rc.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-rc.N** | + +### Generally available +GA images aren't build from scratch but rather promoted from an existing release candidates. When we decide a release candidate has the acceptable quality and QA sings it off, the release candidate is promoted to become the GA release. This makes sure the image has exactly the same content and SHA as the tested release candidate. + +## Support matrix + +Support matrix table shows the version requirements for a particular **scylla-operator** version. Be sure to match these requirements, otherwise some functionality will not work. + +| | v1.9 | v1.8 | v1.7 | v1.6 | v1.5 | v1.4 | v1.3 | v1.2 | v1.1 | v1.0 | +|:-----------------:|:----------:|:----------:|:-----------------:|:--------------------:|:-----------:|:-----------:|:----------:|:----------:|:----------:|:----------:| +| Kubernetes | `>=1.21` | `>=1.21` | `>=1.20 && <1.25` | `>=1.19.10 && <1.25` | `>=1.19.10` | `>=1.19.10` | `>=1.19` | `>=1.19` | `>=1.11` | `>=1.11` | +| CRI API | `v1` | `v1alpha2` | `v1alpha2` | `v1alpha2` | | | | | | | +| Scylla OS | `>=5.0` | `>=5.0` | `>=4.3` | `>=4.3` | `>=4.3` | `>=4.3` | `>=4.2` | `>=4.2` | `>=4.0` | `>=4.0` | +| Scylla Enterprise | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2020.1` | `>=2020.1` | `>=2020.1` | `>=2020.1` | +| Scylla Manager | `>=2.6` | `>=2.6` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | +| Scylla Monitoring | `>=4.0` | `>=4.0` | `>=3.0` | `>=3.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | diff --git a/v1.10/_sources/scylla-cluster-crd.md.txt b/v1.10/_sources/scylla-cluster-crd.md.txt new file mode 100644 index 00000000000..75d34f1a028 --- /dev/null +++ b/v1.10/_sources/scylla-cluster-crd.md.txt @@ -0,0 +1,188 @@ +# Scylla Cluster CRD + +Scylla database clusters can be created and configured using the `clusters.scylla.scylladb.com` custom resource definition (CRD). + +Please refer to the the [user guide walk-through](generic.md) for deployment instructions. +This page will explain all the available configuration options on the Scylla CRD. + +## Sample + +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: simple-cluster + namespace: scylla +spec: + version: 2.3.1 + repository: scylladb/scylla + developerMode: true + cpuset: false + automaticOrphanedNodeCleanup: true + repairs: + - name: "weekly us-east-1 repair" + intensity: "2" + interval: "7d" + dc: ["us-east-1"] + backups: + - name: "daily users backup" + rateLimit: ["50"] + location: ["s3:cluster-backups"] + interval: "1d" + keyspace: ["users"] + - name: "weekly full cluster backup" + rateLimit: ["50"] + location: ["s3:cluster-backups"] + interval: "7d" + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 3 + storage: + capacity: 500G + storageClassName: local-raid-disks + resources: + requests: + cpu: 8 + memory: 32Gi + limits: + cpu: 8 + memory: 32Gi + placement: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: failure-domain.beta.kubernetes.io/region + operator: In + values: + - us-east-1 + - key: failure-domain.beta.kubernetes.io/zone + operator: In + values: + - us-east-1a + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule +``` + +## Settings Explanation + +### Cluster Settings + +* `version`: The version of Scylla to use. It is used as the image tag to pull. +* `agentVersion`: The version of Scylla Manager Agent to use. It is used as the image tag to pull. +* `repository`: Optional field. Specifies a custom image repo. If left unset, the official docker hub repo is used (scylladb/scylla). +* `agentRepository`: Optional field. Specifies a custom Scylla Manager Agent image repo. If left unset, the official docker hub repo is used (scylladb/scylla). +* `developerMode`: Optional field. If it's true, then Scylla is started in [developer mode](https://www.scylladb.com/2016/09/13/test-dev-env/). This setting is for shared test/dev environments. +* `cpuset`: Optional field. If it's true, then the operator will start Scylla with cpu pinning for maximum performance. For this to work, you need to set the kubelet to use the [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and only specify limits in resources. +* `automaticOrphanedNodeCleanup`: Optional field. Controls if automatic orphan node cleanup should be performed. +* `alternator`: Optional field. Defines Alternator configuration. + * `port`: Port on which to bind to Alternator API. + * `writeIsolation`: *required* Desired write isolation. +* `genericUpgrade`: Optional field. Defines GenericUpgrade configuration. + * `failureStrategy`: specifies which logic is executed when upgrade failure happens. Currently only `Retry` is supported. + * `pollInterval`: specifies how often upgrade logic polls on state updates. + Increasing this value should lower number of requests sent to the kube-apiserver, but it may affect + overall time spent during upgrade. +* `datacenter`: Datacenter definition. +* `sysctls`: Optional field. Sysctl properties to be applied during initialization. +* `scyllaArgs`: Optional field. Command line argument passed to Scylla container image. Note: not all Scylla versions support it. +* `network`: Optional field. Allows to customize network parameters. + * `hostNetworking`: controls if host networking should be enabled. + * `dnsPolicy`: controls Scylla Pod DNS Policy. See [details](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy). +* `repairs`: Optional field. Repair tasks definitions. See `Scylla Manager settings` for details. +* `backups`: Optional field. Repair tasks definitions. See `Scylla Manager settings` for details. + + +In the Scylla model, each cluster contains datacenters and each datacenter contains racks. At the moment, the operator only supports single datacenter setups. + +### Scylla Manager settings + +Tasks are scheduled only when Scylla Manager is deployed in K8s cluster. + +Repairs: +* `name` - **required** - human readable name of the task. It must be unique across all tasks. +* `startDate` - specifies the task start date expressed in the RFC3339 format or `now[+duration]`, e.g. `now+3d2h10m`, +valid units are d, h, m, s (default "now"). +* `interval` - Optional field. Task schedule interval e.g. `3d2h10m`, valid units are d, h, m, s (default "0"). +* `numRetries` - Optional field. The number of times a scheduled task will retry to run before failing (default 3). +* `dc` - Optional field. A list of datacenter glob patterns, e.g. `["dc1", "!otherdc*"]` used to specify the DCs to include or exclude from backup. +* `failFast` - Optional field. Stop repair on first error. +* `intensity` - Optional field. Specifies how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. + If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). + Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. + Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. + For Scylla clusters that **do not support row-level repair**, intensity can be a decimal between (0,1). + In that case it specifies percent of shards that can be repaired in parallel on a repair master node. + For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1. + **Intensity is a number passed as string due to lack of support for float values in k8s controller runtime** +* `parallel` - Optional field. Specifies the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). + Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. + The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. + The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2. +* `keyspace` - Optional field. A list of keyspace/tables glob patterns, e.g. `["keyspace", "!keyspace.table_prefix_*"]` +used to include or exclude keyspaces from repair. +* `smallTableThreshold` - Optional field. Enable small table optimization for tables of size lower than given threshold. +Supported units `[B, MiB, GiB, TiB]` (default `"1GiB"`). + +Backups: + +* `name` - **required** - human readable name of the task. It must be unique across all tasks. +* `startDate` - Optional field. Specifies the task start date expressed in the RFC3339 format or `now[+duration]`, e.g. `now+3d2h10m`, +valid units are d, h, m, s (default "now"). +* `interval` - Optional field. task schedule interval e.g. `3d2h10m`, valid units are d, h, m, s (default "0"). +* `numRetries` - Optional field. the number of times a scheduled task will retry to run before failing (default 3). +* `dc` - Optional field. A list of datacenter glob patterns, e.g. `["dc1","!otherdc*"]` used to specify the DCs to include or exclude from backup. +* `keyspace` - Optional field. A list of keyspace/tables glob patterns, e.g. `["keyspace","!keyspace.table_prefix_*"]` used to include or exclude keyspaces from backup. +* `location` - Optional field. A list of backup locations in the format `[:]:` ex. `s3:my-bucket`. +The `:` part is optional and is only needed when different datacenters are being used to upload data to different locations. +`` Optional field. must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. +The only supported storage at the moment are `s3` and `gcs`. +* `rateLimit` - Optional field. A list of megabytes (MiB) per second rate limits expressed in the format `[:]`. +The `:` part is optional and only needed when different datacenters need different upload limits. +Set to 0 for no limit (default 100). +* `retention` - Optional field. The number of backups which are to be stored (default 3). +* `snapshotParallel` - Optional field. A list of snapshot parallelism limits in the format `[:]`. +The `:` part is optional and allows for specifying different limits in selected datacenters. +If The `:` part is not set, the limit is global (e.g. `["dc1:2,5"]`) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters. +* `uploadParallel` - Optional field. A list of upload parallelism limits in the format `[:]`. +The `:` part is optional and allows for specifying different limits in selected datacenters. +If The `:` part is not set the limit is global (e.g. `["dc1:2,5"]`) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters. + + +### Datacenter Settings + +* `name`: Name of the datacenter. Usually, a datacenter corresponds to a region. +* `racks`: List of racks for the specific datacenter. + +### Rack Settings + +* `name`: Name of the rack. Usually, a rack corresponds to an availability zone. +* `members`: Number of Scylla members for the specific rack. (In Scylla documentation, they are called nodes. We don't call them nodes to avoid confusion as a Scylla Node corresponds to a Kubernetes Pod, not a Kubernetes Node). +* `storage`: Defines the specs of the underlying storage. + * `capacity`: Capacity of the PersistentVolume to request. + * `storageClassName`: Optional field. [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) of PersistentVolume to request. +* `resources`: Defines the CPU and RAM resources for the Scylla Pods. + * `requests`: The minimum amount of resources needed to run a Scylla container. + * `cpu`: CPU requests. + * `memory`: RAM requests. + * `limits`: The maximum amount of resources that can be used by a Scylla container. + * `cpu`: CPU limits. + * `memory`: RAM limits. +* `agentResources`: Optional field. Defines the CPU and RAM resources for the Scylla Manager Agent container. See `resources` for details. +* `volumes`: Optional field. Defines volumes available in Scylla Pod. See [details](https://kubernetes.io/docs/concepts/storage/volumes/). +* `volumeMounts`: Optional field. Defines which volumes will be attached to Scylla container. +* `agentVolumeMounts`: Optional field. Defines which volumes will be attached to Agent container. +* `scyllaConfig`: Optional field. name of custom config map which will be merged with Scylla config. +* `scyllaAgentConfig`: Optional field. name of custom secret which will be merged with Scylla Manager Agent config. +* `placement`: Optional field. Defines the placement of Scylla Pods. Has the following subfields: + * [`nodeAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature) + * [`podAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature) + * [`podAntiAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature) + * [`tolerations`](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration) diff --git a/v1.10/_sources/upgrade.md.txt b/v1.10/_sources/upgrade.md.txt new file mode 100644 index 00000000000..ab14157256b --- /dev/null +++ b/v1.10/_sources/upgrade.md.txt @@ -0,0 +1,184 @@ +# Upgrade of Scylla Operator + +This page describes Scylla Operator upgrade procedures. +There are two generic update procedures - via Helm and via kubectl. Before upgrading, please check this page to find out +if your target version requires additional upgrade steps. + +## Upgrade via Helm + +Helm doesn't support managing CustomResourceDefinition resources ([#5871](https://github.com/helm/helm/issues/5871), [#7735](https://github.com/helm/helm/issues/7735)) +These are only created on first install and never updated. In order to update them, users have to do it manually. + +Replace `` with the name of your Helm release for Scylla Operator and replace `` with the version number you want to install: +1. Make sure Helm chart repository is up-to-date: + ``` + helm repo add scylla-operator https://storage.googleapis.com/scylla-operator-charts/stable + helm repo update + ``` +2. Update CRD resources. We recommend using `--server-side` flag for `kubectl apply`, if your version supports it. + ``` + tmpdir=$( mktemp -d ) \ + && helm pull scylla-operator/scylla-operator --version --untar --untardir "${tmpdir}" \ + && find "${tmpdir}"/scylla-operator/crds/ -name '*.yaml' -printf '-f=%p ' \ + | xargs kubectl apply + ``` +3. Update Scylla Operator + ``` + helm upgrade --version scylla-operator/scylla-operator + ``` + +## Upgrade via kubectl + +Replace `` with the version number you want to install: + +1. Checkout source code of version you want to use: + ``` + git checkout + ``` +2. Manifests use rolling minor version tag, you may want to pin it to specific version: + ``` + find deploy/operator -name "*.yaml" | xargs sed --follow-symlinks -i -E "s^docker.io/scylladb/scylla-operator:[0-9]+\.[0-9]+^docker.io/scylladb/scylla-operator:^g" + ``` +3. Update Scylla Operator. We recommend using `--server-side` flag for `kubectl apply`, if your version supports it. + ``` + kubectl apply -f deploy/operator + ``` + +--- + +## `v1.2.0` -> `v1.3.0` + +Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure. + +1. Checkout source code of v1.3.0: + ``` + git checkout v1.3.0 + ``` +1. Update Scylla Operator from deploy directory: + ``` + kubectl -n scylla-operator apply -f deploy/operator + ``` +1. Wait until Scylla Operator is up and running: + ``` + kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com + kubectl -n scylla-operator rollout status deployment.apps/scylla-operator + ``` + +## `v1.1.0` -> `v1.2.0` + +1.2.0 release brought a lot of changes to the Scylla Operator deployment process. +To properly update Scylla Operator one must delete old objects and install updated ones. + +Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure. + +1. Checkout source code of v1.2.0: + ``` + git checkout v1.2.0 + ``` +1. Remove old scylla operator namespace - in our case it's called `scylla-operator-system`: + ``` + kubectl delete namespace scylla-operator-system --wait=true + ``` +1. Remove old webhooks: + ``` + kubectl delete MutatingWebhookConfiguration scylla-operator-mutating-webhook-configuration + kubectl delete ValidatingWebhookConfiguration scylla-operator-validating-webhook-configuration + ``` +1. Install Scylla Operator from deploy directory: + ``` + kubectl -n scylla-operator apply -f deploy/operator + ``` +1. Wait until Scylla Operator is up and running: + ``` + kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com + kubectl -n scylla-operator rollout status deployment.apps/scylla-operator + ``` + +## `v1.0.0` -> `v1.1.0` + +During this update we will change probes and image for Scylla Operator. +A new version brings an automation for upgrade of sidecar image, so a rolling restart of managed Scylla clusters is expected. + +1. Get name of StatefulSet managing Scylla Operator + ```shell + kubectl --namespace scylla-operator-system get sts --selector="control-plane=controller-manager" + + NAME READY AGE + scylla-operator-controller-manager 1/1 95m + ``` + +1. Change probes and used container image by applying following patch: + ```yaml + spec: + template: + spec: + containers: + - name: manager + image: docker.io/scylladb/scylla-operator:1.1.0 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + scheme: HTTP + readinessProbe: + $retainKeys: + - httpGet + httpGet: + path: /readyz + port: 8080 + scheme: HTTP + ``` + To apply above patch save it to file (`operator-patch.yaml` for example) and apply to Operator StatefulSet: + ```shell + kubectl -n scylla-operator-system patch sts scylla-operator-controller-manager --patch "$(cat operator-patch.yaml)" + ``` + + +## `v0.3.0` -> `v1.0.0` + +***Note:*** There's an experimental migration procedure available [here](migration.md). + +`v0.3.0` used a very common name as a CRD kind (`Cluster`). In `v1.0.0` this issue was solved by using less common +kind which is easier to disambiguate. (`ScyllaCluster`). +This change is backward incompatible, so Scylla cluster must be turned off and recreated from scratch. +In case you need to preserve your data, refer to backup and restore guide. + +1. Get list of existing Scylla clusters + ``` + kubectl -n scylla get cluster.scylla.scylladb.com + + NAME AGE + simple-cluster 30m + ``` +1. Delete each one of them + + ``` + kubectl -n scylla delete cluster.scylla.scylladb.com simple-cluster + ``` +1. Make sure you're on `v0.3.0` branch + ``` + git checkout v0.3.0 + ``` +1. Delete existing CRD and Operator + ``` + kubectl delete -f examples/generic/operator.yaml + ``` +1. Checkout `v1.0.0` version + ``` + git checkout v1.0.0 + ``` +1. Install new CRD and Scylla Operator + ``` + kubectl apply -f examples/common/operator.yaml + ``` +1. Migrate your existing Scylla Cluster definition. Change `apiVersion` and `kind` from: + ``` + apiVersion: scylla.scylladb.com/v1alpha1 + kind: Cluster + ``` + to: + ``` + apiVersion: scylla.scylladb.com/v1 + kind: ScyllaCluster + ``` +1. Once your cluster definition is ready, use `kubectl apply` to install fresh Scylla cluster. diff --git a/v1.10/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/v1.10/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000000..eb19f698afc --- /dev/null +++ b/v1.10/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/v1.10/_sphinx_design_static/design-tabs.js b/v1.10/_sphinx_design_static/design-tabs.js new file mode 100644 index 00000000000..36b38cf0d91 --- /dev/null +++ b/v1.10/_sphinx_design_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/v1.10/_static/basic.css b/v1.10/_static/basic.css new file mode 100644 index 00000000000..30fee9d0f76 --- /dev/null +++ b/v1.10/_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/v1.10/_static/check-solid.svg b/v1.10/_static/check-solid.svg new file mode 100644 index 00000000000..92fad4b5c0b --- /dev/null +++ b/v1.10/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v1.10/_static/clipboard.min.js b/v1.10/_static/clipboard.min.js new file mode 100644 index 00000000000..54b3c463811 --- /dev/null +++ b/v1.10/_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/v1.10/_static/copybutton.css b/v1.10/_static/copybutton.css new file mode 100644 index 00000000000..f1916ec7d1b --- /dev/null +++ b/v1.10/_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/v1.10/_static/copybutton.js b/v1.10/_static/copybutton.js new file mode 100644 index 00000000000..2ea7ff3e217 --- /dev/null +++ b/v1.10/_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/v1.10/_static/copybutton_funcs.js b/v1.10/_static/copybutton_funcs.js new file mode 100644 index 00000000000..dbe1aaad79c --- /dev/null +++ b/v1.10/_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/v1.10/_static/css/main.css b/v1.10/_static/css/main.css new file mode 100644 index 00000000000..65eb0a55363 --- /dev/null +++ b/v1.10/_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/v1.10/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/v1.10/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000000..eb19f698afc --- /dev/null +++ b/v1.10/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/v1.10/_static/design-tabs.js b/v1.10/_static/design-tabs.js new file mode 100644 index 00000000000..36b38cf0d91 --- /dev/null +++ b/v1.10/_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/v1.10/_static/doctools.js b/v1.10/_static/doctools.js new file mode 100644 index 00000000000..d06a71d7518 --- /dev/null +++ b/v1.10/_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/v1.10/_static/documentation_options.js b/v1.10/_static/documentation_options.js new file mode 100644 index 00000000000..7e4c114f212 --- /dev/null +++ b/v1.10/_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/v1.10/_static/file.png b/v1.10/_static/file.png new file mode 100644 index 00000000000..a858a410e4f Binary files /dev/null and b/v1.10/_static/file.png differ diff --git a/v1.10/_static/img/banner-background.svg b/v1.10/_static/img/banner-background.svg new file mode 100644 index 00000000000..f8520d5b3e4 --- /dev/null +++ b/v1.10/_static/img/banner-background.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v1.10/_static/img/favicon-228x228.png b/v1.10/_static/img/favicon-228x228.png new file mode 100644 index 00000000000..f30770c7edd Binary files /dev/null and b/v1.10/_static/img/favicon-228x228.png differ diff --git a/v1.10/_static/img/favicon-32x32.png b/v1.10/_static/img/favicon-32x32.png new file mode 100644 index 00000000000..aae1708f26f Binary files /dev/null and b/v1.10/_static/img/favicon-32x32.png differ diff --git a/v1.10/_static/img/favicon.ico b/v1.10/_static/img/favicon.ico new file mode 100644 index 00000000000..6c7484f082f Binary files /dev/null and b/v1.10/_static/img/favicon.ico differ diff --git a/v1.10/_static/img/icons/icon-about-team.svg b/v1.10/_static/img/icons/icon-about-team.svg new file mode 100644 index 00000000000..5448c7f007b --- /dev/null +++ b/v1.10/_static/img/icons/icon-about-team.svg @@ -0,0 +1 @@ +icon-about-team diff --git a/v1.10/_static/img/icons/icon-about-us-m.svg b/v1.10/_static/img/icons/icon-about-us-m.svg new file mode 100644 index 00000000000..09107d9520a --- /dev/null +++ b/v1.10/_static/img/icons/icon-about-us-m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.10/_static/img/icons/icon-about-us.svg b/v1.10/_static/img/icons/icon-about-us.svg new file mode 100644 index 00000000000..1b1fcc83e30 --- /dev/null +++ b/v1.10/_static/img/icons/icon-about-us.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.10/_static/img/icons/icon-alternator.svg b/v1.10/_static/img/icons/icon-alternator.svg new file mode 100644 index 00000000000..7c2b4ebae0d --- /dev/null +++ b/v1.10/_static/img/icons/icon-alternator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.10/_static/img/icons/icon-apps.svg b/v1.10/_static/img/icons/icon-apps.svg new file mode 100644 index 00000000000..7e93612026b --- /dev/null +++ b/v1.10/_static/img/icons/icon-apps.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-architecture.svg b/v1.10/_static/img/icons/icon-architecture.svg new file mode 100644 index 00000000000..67ebbc2f38c --- /dev/null +++ b/v1.10/_static/img/icons/icon-architecture.svg @@ -0,0 +1 @@ +icon-architecture diff --git a/v1.10/_static/img/icons/icon-benchmarks.svg b/v1.10/_static/img/icons/icon-benchmarks.svg new file mode 100644 index 00000000000..e1ce2c1d784 --- /dev/null +++ b/v1.10/_static/img/icons/icon-benchmarks.svg @@ -0,0 +1 @@ +icon-benchmarks diff --git a/v1.10/_static/img/icons/icon-blog.svg b/v1.10/_static/img/icons/icon-blog.svg new file mode 100644 index 00000000000..f4096cbf111 --- /dev/null +++ b/v1.10/_static/img/icons/icon-blog.svg @@ -0,0 +1 @@ +icon-blog2 diff --git a/v1.10/_static/img/icons/icon-careers.svg b/v1.10/_static/img/icons/icon-careers.svg new file mode 100644 index 00000000000..2a7c6ea0b74 --- /dev/null +++ b/v1.10/_static/img/icons/icon-careers.svg @@ -0,0 +1 @@ +icon-careers diff --git a/v1.10/_static/img/icons/icon-chevron-left.svg b/v1.10/_static/img/icons/icon-chevron-left.svg new file mode 100644 index 00000000000..3afa25c4812 --- /dev/null +++ b/v1.10/_static/img/icons/icon-chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.10/_static/img/icons/icon-chevron-right.svg b/v1.10/_static/img/icons/icon-chevron-right.svg new file mode 100644 index 00000000000..44eb829cdcb --- /dev/null +++ b/v1.10/_static/img/icons/icon-chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.10/_static/img/icons/icon-circe.svg b/v1.10/_static/img/icons/icon-circe.svg new file mode 100644 index 00000000000..875e4216707 --- /dev/null +++ b/v1.10/_static/img/icons/icon-circe.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-clock.svg b/v1.10/_static/img/icons/icon-clock.svg new file mode 100644 index 00000000000..8c924698089 --- /dev/null +++ b/v1.10/_static/img/icons/icon-clock.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-close.svg b/v1.10/_static/img/icons/icon-close.svg new file mode 100644 index 00000000000..d1162b73e73 --- /dev/null +++ b/v1.10/_static/img/icons/icon-close.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/v1.10/_static/img/icons/icon-cloud-docs.svg b/v1.10/_static/img/icons/icon-cloud-docs.svg new file mode 100644 index 00000000000..a9069bb6e5c --- /dev/null +++ b/v1.10/_static/img/icons/icon-cloud-docs.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-cloud.svg b/v1.10/_static/img/icons/icon-cloud.svg new file mode 100644 index 00000000000..cfb2318daef --- /dev/null +++ b/v1.10/_static/img/icons/icon-cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.10/_static/img/icons/icon-comparison.svg b/v1.10/_static/img/icons/icon-comparison.svg new file mode 100644 index 00000000000..49d809a5df4 --- /dev/null +++ b/v1.10/_static/img/icons/icon-comparison.svg @@ -0,0 +1 @@ +icon-comparison diff --git a/v1.10/_static/img/icons/icon-contact-us.svg b/v1.10/_static/img/icons/icon-contact-us.svg new file mode 100644 index 00000000000..9df3145dd21 --- /dev/null +++ b/v1.10/_static/img/icons/icon-contact-us.svg @@ -0,0 +1 @@ +icon-contact-us diff --git a/v1.10/_static/img/icons/icon-developers-blog.svg b/v1.10/_static/img/icons/icon-developers-blog.svg new file mode 100644 index 00000000000..ee804197a0b --- /dev/null +++ b/v1.10/_static/img/icons/icon-developers-blog.svg @@ -0,0 +1 @@ +icon-developers-blog diff --git a/v1.10/_static/img/icons/icon-docs.svg b/v1.10/_static/img/icons/icon-docs.svg new file mode 100644 index 00000000000..5501492f3e0 --- /dev/null +++ b/v1.10/_static/img/icons/icon-docs.svg @@ -0,0 +1 @@ +icon-docs diff --git a/v1.10/_static/img/icons/icon-enterprise-m.svg b/v1.10/_static/img/icons/icon-enterprise-m.svg new file mode 100644 index 00000000000..97be900b501 --- /dev/null +++ b/v1.10/_static/img/icons/icon-enterprise-m.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.10/_static/img/icons/icon-enterprise.svg b/v1.10/_static/img/icons/icon-enterprise.svg new file mode 100644 index 00000000000..ee1ac26283d --- /dev/null +++ b/v1.10/_static/img/icons/icon-enterprise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.10/_static/img/icons/icon-events.svg b/v1.10/_static/img/icons/icon-events.svg new file mode 100644 index 00000000000..ba5f2118644 --- /dev/null +++ b/v1.10/_static/img/icons/icon-events.svg @@ -0,0 +1 @@ +icon-events diff --git a/v1.10/_static/img/icons/icon-exclamation.svg b/v1.10/_static/img/icons/icon-exclamation.svg new file mode 100644 index 00000000000..a7eb4b77a42 --- /dev/null +++ b/v1.10/_static/img/icons/icon-exclamation.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v1.10/_static/img/icons/icon-expand.svg b/v1.10/_static/img/icons/icon-expand.svg new file mode 100644 index 00000000000..38065653675 --- /dev/null +++ b/v1.10/_static/img/icons/icon-expand.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/v1.10/_static/img/icons/icon-forum.svg b/v1.10/_static/img/icons/icon-forum.svg new file mode 100644 index 00000000000..37a709f7a8f --- /dev/null +++ b/v1.10/_static/img/icons/icon-forum.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-getting-started.svg b/v1.10/_static/img/icons/icon-getting-started.svg new file mode 100644 index 00000000000..702500be409 --- /dev/null +++ b/v1.10/_static/img/icons/icon-getting-started.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-glossary.svg b/v1.10/_static/img/icons/icon-glossary.svg new file mode 100644 index 00000000000..e8329c2afee --- /dev/null +++ b/v1.10/_static/img/icons/icon-glossary.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-home.svg b/v1.10/_static/img/icons/icon-home.svg new file mode 100644 index 00000000000..f0b9c25419c --- /dev/null +++ b/v1.10/_static/img/icons/icon-home.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-infoworld.svg b/v1.10/_static/img/icons/icon-infoworld.svg new file mode 100644 index 00000000000..906e87279c2 --- /dev/null +++ b/v1.10/_static/img/icons/icon-infoworld.svg @@ -0,0 +1 @@ +icon-infoworld diff --git a/v1.10/_static/img/icons/icon-integrations.svg b/v1.10/_static/img/icons/icon-integrations.svg new file mode 100644 index 00000000000..1ef0920d49e --- /dev/null +++ b/v1.10/_static/img/icons/icon-integrations.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-knowledge-base.svg b/v1.10/_static/img/icons/icon-knowledge-base.svg new file mode 100644 index 00000000000..884451270d2 --- /dev/null +++ b/v1.10/_static/img/icons/icon-knowledge-base.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-less.svg b/v1.10/_static/img/icons/icon-less.svg new file mode 100644 index 00000000000..3094127decf --- /dev/null +++ b/v1.10/_static/img/icons/icon-less.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v1.10/_static/img/icons/icon-live-test.svg b/v1.10/_static/img/icons/icon-live-test.svg new file mode 100644 index 00000000000..dcb5916c264 --- /dev/null +++ b/v1.10/_static/img/icons/icon-live-test.svg @@ -0,0 +1 @@ +icon-live-test diff --git a/v1.10/_static/img/icons/icon-mail-list.svg b/v1.10/_static/img/icons/icon-mail-list.svg new file mode 100644 index 00000000000..0e6192a352c --- /dev/null +++ b/v1.10/_static/img/icons/icon-mail-list.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-manager.svg b/v1.10/_static/img/icons/icon-manager.svg new file mode 100644 index 00000000000..02b4e425beb --- /dev/null +++ b/v1.10/_static/img/icons/icon-manager.svg @@ -0,0 +1 @@ +icon-manager diff --git a/v1.10/_static/img/icons/icon-memory-management.svg b/v1.10/_static/img/icons/icon-memory-management.svg new file mode 100644 index 00000000000..e34eb4504f7 --- /dev/null +++ b/v1.10/_static/img/icons/icon-memory-management.svg @@ -0,0 +1 @@ +icon-memory-management diff --git a/v1.10/_static/img/icons/icon-modeling.svg b/v1.10/_static/img/icons/icon-modeling.svg new file mode 100644 index 00000000000..97fa3a0e213 --- /dev/null +++ b/v1.10/_static/img/icons/icon-modeling.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-monitoring.svg b/v1.10/_static/img/icons/icon-monitoring.svg new file mode 100644 index 00000000000..80b3787f668 --- /dev/null +++ b/v1.10/_static/img/icons/icon-monitoring.svg @@ -0,0 +1 @@ +icon-monitoring diff --git a/v1.10/_static/img/icons/icon-networking.svg b/v1.10/_static/img/icons/icon-networking.svg new file mode 100644 index 00000000000..40a3fd5f6f1 --- /dev/null +++ b/v1.10/_static/img/icons/icon-networking.svg @@ -0,0 +1 @@ +icon-networking diff --git a/v1.10/_static/img/icons/icon-news.svg b/v1.10/_static/img/icons/icon-news.svg new file mode 100644 index 00000000000..a952b59937d --- /dev/null +++ b/v1.10/_static/img/icons/icon-news.svg @@ -0,0 +1 @@ +icon-news diff --git a/v1.10/_static/img/icons/icon-newsletter.svg b/v1.10/_static/img/icons/icon-newsletter.svg new file mode 100644 index 00000000000..5b8d47eb157 --- /dev/null +++ b/v1.10/_static/img/icons/icon-newsletter.svg @@ -0,0 +1 @@ +icon-newsletter diff --git a/v1.10/_static/img/icons/icon-nsql-guides.svg b/v1.10/_static/img/icons/icon-nsql-guides.svg new file mode 100644 index 00000000000..60ebab37953 --- /dev/null +++ b/v1.10/_static/img/icons/icon-nsql-guides.svg @@ -0,0 +1 @@ +icon-nsql-guides diff --git a/v1.10/_static/img/icons/icon-open-source.svg b/v1.10/_static/img/icons/icon-open-source.svg new file mode 100644 index 00000000000..98c2ea7d5bf --- /dev/null +++ b/v1.10/_static/img/icons/icon-open-source.svg @@ -0,0 +1 @@ +icon-open-source diff --git a/v1.10/_static/img/icons/icon-operator.svg b/v1.10/_static/img/icons/icon-operator.svg new file mode 100644 index 00000000000..bb7d8d3ea86 --- /dev/null +++ b/v1.10/_static/img/icons/icon-operator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.10/_static/img/icons/icon-overview.svg b/v1.10/_static/img/icons/icon-overview.svg new file mode 100644 index 00000000000..515c1528a2a --- /dev/null +++ b/v1.10/_static/img/icons/icon-overview.svg @@ -0,0 +1 @@ +icon-overview diff --git a/v1.10/_static/img/icons/icon-partners.svg b/v1.10/_static/img/icons/icon-partners.svg new file mode 100644 index 00000000000..d0146fc4972 --- /dev/null +++ b/v1.10/_static/img/icons/icon-partners.svg @@ -0,0 +1 @@ +icon-partners diff --git a/v1.10/_static/img/icons/icon-plus.svg b/v1.10/_static/img/icons/icon-plus.svg new file mode 100644 index 00000000000..5757435085a --- /dev/null +++ b/v1.10/_static/img/icons/icon-plus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v1.10/_static/img/icons/icon-pricing.svg b/v1.10/_static/img/icons/icon-pricing.svg new file mode 100644 index 00000000000..74b01db1684 --- /dev/null +++ b/v1.10/_static/img/icons/icon-pricing.svg @@ -0,0 +1 @@ +icon-pricing$ diff --git a/v1.10/_static/img/icons/icon-release-notes.svg b/v1.10/_static/img/icons/icon-release-notes.svg new file mode 100644 index 00000000000..80c490c7b01 --- /dev/null +++ b/v1.10/_static/img/icons/icon-release-notes.svg @@ -0,0 +1 @@ +icon-release-notes diff --git a/v1.10/_static/img/icons/icon-resource-center.svg b/v1.10/_static/img/icons/icon-resource-center.svg new file mode 100644 index 00000000000..6e3ab08e792 --- /dev/null +++ b/v1.10/_static/img/icons/icon-resource-center.svg @@ -0,0 +1 @@ +icon-ressource-center diff --git a/v1.10/_static/img/icons/icon-roadmap.svg b/v1.10/_static/img/icons/icon-roadmap.svg new file mode 100644 index 00000000000..c8cbf67c8cf --- /dev/null +++ b/v1.10/_static/img/icons/icon-roadmap.svg @@ -0,0 +1 @@ +icon-roadmap-4 diff --git a/v1.10/_static/img/icons/icon-search.svg b/v1.10/_static/img/icons/icon-search.svg new file mode 100644 index 00000000000..81aae93eef6 --- /dev/null +++ b/v1.10/_static/img/icons/icon-search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v1.10/_static/img/icons/icon-slack.svg b/v1.10/_static/img/icons/icon-slack.svg new file mode 100644 index 00000000000..fc164ea1e77 --- /dev/null +++ b/v1.10/_static/img/icons/icon-slack.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-stack-overflow.svg b/v1.10/_static/img/icons/icon-stack-overflow.svg new file mode 100644 index 00000000000..bebe9b82742 --- /dev/null +++ b/v1.10/_static/img/icons/icon-stack-overflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v1.10/_static/img/icons/icon-summit.svg b/v1.10/_static/img/icons/icon-summit.svg new file mode 100644 index 00000000000..4b900bd0c0a --- /dev/null +++ b/v1.10/_static/img/icons/icon-summit.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/icons/icon-support.svg b/v1.10/_static/img/icons/icon-support.svg new file mode 100644 index 00000000000..a4228b34e86 --- /dev/null +++ b/v1.10/_static/img/icons/icon-support.svg @@ -0,0 +1 @@ +icon-support diff --git a/v1.10/_static/img/icons/icon-tech-talks.svg b/v1.10/_static/img/icons/icon-tech-talks.svg new file mode 100644 index 00000000000..df42b5522ba --- /dev/null +++ b/v1.10/_static/img/icons/icon-tech-talks.svg @@ -0,0 +1 @@ +icon-tech-talks diff --git a/v1.10/_static/img/icons/icon-testing.svg b/v1.10/_static/img/icons/icon-testing.svg new file mode 100644 index 00000000000..2fe54efdbc3 --- /dev/null +++ b/v1.10/_static/img/icons/icon-testing.svg @@ -0,0 +1 @@ +icon-testing diff --git a/v1.10/_static/img/icons/icon-thumbs-down.svg b/v1.10/_static/img/icons/icon-thumbs-down.svg new file mode 100644 index 00000000000..3e7bcd6d905 --- /dev/null +++ b/v1.10/_static/img/icons/icon-thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.10/_static/img/icons/icon-thumbs-up.svg b/v1.10/_static/img/icons/icon-thumbs-up.svg new file mode 100644 index 00000000000..226c44d853c --- /dev/null +++ b/v1.10/_static/img/icons/icon-thumbs-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.10/_static/img/icons/icon-tip.svg b/v1.10/_static/img/icons/icon-tip.svg new file mode 100644 index 00000000000..bf7aa6af840 --- /dev/null +++ b/v1.10/_static/img/icons/icon-tip.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/v1.10/_static/img/icons/icon-training.svg b/v1.10/_static/img/icons/icon-training.svg new file mode 100644 index 00000000000..08b95a88eda --- /dev/null +++ b/v1.10/_static/img/icons/icon-training.svg @@ -0,0 +1 @@ +icon-training diff --git a/v1.10/_static/img/icons/icon-triangle-down.svg b/v1.10/_static/img/icons/icon-triangle-down.svg new file mode 100644 index 00000000000..e8ae088106f --- /dev/null +++ b/v1.10/_static/img/icons/icon-triangle-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.10/_static/img/icons/icon-university.svg b/v1.10/_static/img/icons/icon-university.svg new file mode 100644 index 00000000000..f7547ab9599 --- /dev/null +++ b/v1.10/_static/img/icons/icon-university.svg @@ -0,0 +1 @@ +icon-university diff --git a/v1.10/_static/img/icons/icon-users-blog.svg b/v1.10/_static/img/icons/icon-users-blog.svg new file mode 100644 index 00000000000..47e56cddcf7 --- /dev/null +++ b/v1.10/_static/img/icons/icon-users-blog.svg @@ -0,0 +1 @@ +icon-users-blog diff --git a/v1.10/_static/img/icons/icon-warning.svg b/v1.10/_static/img/icons/icon-warning.svg new file mode 100644 index 00000000000..e4b1d40331b --- /dev/null +++ b/v1.10/_static/img/icons/icon-warning.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v1.10/_static/img/icons/icon-webinars.svg b/v1.10/_static/img/icons/icon-webinars.svg new file mode 100644 index 00000000000..5e9f5cd4270 --- /dev/null +++ b/v1.10/_static/img/icons/icon-webinars.svg @@ -0,0 +1 @@ +icon-webinars diff --git a/v1.10/_static/img/icons/icon-whitepapers.svg b/v1.10/_static/img/icons/icon-whitepapers.svg new file mode 100644 index 00000000000..3351e51d23c --- /dev/null +++ b/v1.10/_static/img/icons/icon-whitepapers.svg @@ -0,0 +1 @@ +icon-whitepapers diff --git a/v1.10/_static/img/icons/icon-workshop.svg b/v1.10/_static/img/icons/icon-workshop.svg new file mode 100644 index 00000000000..5206e58e986 --- /dev/null +++ b/v1.10/_static/img/icons/icon-workshop.svg @@ -0,0 +1 @@ + diff --git a/v1.10/_static/img/logo-docs.svg b/v1.10/_static/img/logo-docs.svg new file mode 100644 index 00000000000..4fff669cb6f --- /dev/null +++ b/v1.10/_static/img/logo-docs.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.10/_static/img/logo-scylla-horizontal-RGB.svg b/v1.10/_static/img/logo-scylla-horizontal-RGB.svg new file mode 100644 index 00000000000..b5022d7c4dc --- /dev/null +++ b/v1.10/_static/img/logo-scylla-horizontal-RGB.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.10/_static/img/mascots/404.jpg b/v1.10/_static/img/mascots/404.jpg new file mode 100644 index 00000000000..769fa0889f8 Binary files /dev/null and b/v1.10/_static/img/mascots/404.jpg differ diff --git a/v1.10/_static/img/mascots/scylla-3monsters.png b/v1.10/_static/img/mascots/scylla-3monsters.png new file mode 100644 index 00000000000..7c06d01674a Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-3monsters.png differ diff --git a/v1.10/_static/img/mascots/scylla-advisor-crystal.png b/v1.10/_static/img/mascots/scylla-advisor-crystal.png new file mode 100644 index 00000000000..d33fddd62f0 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-advisor-crystal.png differ diff --git a/v1.10/_static/img/mascots/scylla-alternator.svg b/v1.10/_static/img/mascots/scylla-alternator.svg new file mode 100644 index 00000000000..0462f893d5f --- /dev/null +++ b/v1.10/_static/img/mascots/scylla-alternator.svg @@ -0,0 +1 @@ +scylla-alternator diff --git a/v1.10/_static/img/mascots/scylla-cloud.svg b/v1.10/_static/img/mascots/scylla-cloud.svg new file mode 100644 index 00000000000..a6c6a26fc99 --- /dev/null +++ b/v1.10/_static/img/mascots/scylla-cloud.svg @@ -0,0 +1 @@ +scylla-cloud diff --git a/v1.10/_static/img/mascots/scylla-computer-3-monsters.png b/v1.10/_static/img/mascots/scylla-computer-3-monsters.png new file mode 100644 index 00000000000..d0368a7027b Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-computer-3-monsters.png differ diff --git a/v1.10/_static/img/mascots/scylla-computer-headset.png b/v1.10/_static/img/mascots/scylla-computer-headset.png new file mode 100644 index 00000000000..0cdadaa2167 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-computer-headset.png differ diff --git a/v1.10/_static/img/mascots/scylla-cup-number-one.png b/v1.10/_static/img/mascots/scylla-cup-number-one.png new file mode 100644 index 00000000000..e889f4e368e Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-cup-number-one.png differ diff --git a/v1.10/_static/img/mascots/scylla-docs.svg b/v1.10/_static/img/mascots/scylla-docs.svg new file mode 100644 index 00000000000..a5bce950c25 --- /dev/null +++ b/v1.10/_static/img/mascots/scylla-docs.svg @@ -0,0 +1 @@ +scylla-docs diff --git a/v1.10/_static/img/mascots/scylla-drivers.svg b/v1.10/_static/img/mascots/scylla-drivers.svg new file mode 100644 index 00000000000..6012e71679b --- /dev/null +++ b/v1.10/_static/img/mascots/scylla-drivers.svg @@ -0,0 +1 @@ +scylla-manager diff --git a/v1.10/_static/img/mascots/scylla-enterprise.svg b/v1.10/_static/img/mascots/scylla-enterprise.svg new file mode 100644 index 00000000000..a1aa0b46ac1 --- /dev/null +++ b/v1.10/_static/img/mascots/scylla-enterprise.svg @@ -0,0 +1 @@ +scylla-enterprise diff --git a/v1.10/_static/img/mascots/scylla-forklift-boxes.png b/v1.10/_static/img/mascots/scylla-forklift-boxes.png new file mode 100644 index 00000000000..f64c29e6c7c Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-forklift-boxes.png differ diff --git a/v1.10/_static/img/mascots/scylla-forklift-migration.png b/v1.10/_static/img/mascots/scylla-forklift-migration.png new file mode 100644 index 00000000000..d2f645c645a Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-forklift-migration.png differ diff --git a/v1.10/_static/img/mascots/scylla-gear.png b/v1.10/_static/img/mascots/scylla-gear.png new file mode 100644 index 00000000000..0f53b26afa5 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-gear.png differ diff --git a/v1.10/_static/img/mascots/scylla-hardhat.png b/v1.10/_static/img/mascots/scylla-hardhat.png new file mode 100644 index 00000000000..630f2d90942 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-hardhat.png differ diff --git a/v1.10/_static/img/mascots/scylla-headband.png b/v1.10/_static/img/mascots/scylla-headband.png new file mode 100644 index 00000000000..c87abe684d5 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-headband.png differ diff --git a/v1.10/_static/img/mascots/scylla-headset.png b/v1.10/_static/img/mascots/scylla-headset.png new file mode 100644 index 00000000000..ba52cd223db Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-headset.png differ diff --git a/v1.10/_static/img/mascots/scylla-hearts.png b/v1.10/_static/img/mascots/scylla-hearts.png new file mode 100644 index 00000000000..cef08c8654a Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-hearts.png differ diff --git a/v1.10/_static/img/mascots/scylla-looking-down.png b/v1.10/_static/img/mascots/scylla-looking-down.png new file mode 100644 index 00000000000..75cccbfdf12 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-looking-down.png differ diff --git a/v1.10/_static/img/mascots/scylla-looking-up.png b/v1.10/_static/img/mascots/scylla-looking-up.png new file mode 100644 index 00000000000..6f10405f218 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-looking-up.png differ diff --git a/v1.10/_static/img/mascots/scylla-magnifying-glass-fronting.png b/v1.10/_static/img/mascots/scylla-magnifying-glass-fronting.png new file mode 100644 index 00000000000..e368cae169c Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-magnifying-glass-fronting.png differ diff --git a/v1.10/_static/img/mascots/scylla-magnifying-glass.png b/v1.10/_static/img/mascots/scylla-magnifying-glass.png new file mode 100644 index 00000000000..74ad6695005 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-magnifying-glass.png differ diff --git a/v1.10/_static/img/mascots/scylla-manager.svg b/v1.10/_static/img/mascots/scylla-manager.svg new file mode 100644 index 00000000000..6ba9ed937c9 --- /dev/null +++ b/v1.10/_static/img/mascots/scylla-manager.svg @@ -0,0 +1 @@ +scylla-manager-2 diff --git a/v1.10/_static/img/mascots/scylla-monitor.svg b/v1.10/_static/img/mascots/scylla-monitor.svg new file mode 100644 index 00000000000..48bec7dde32 --- /dev/null +++ b/v1.10/_static/img/mascots/scylla-monitor.svg @@ -0,0 +1 @@ +scylla-monitor diff --git a/v1.10/_static/img/mascots/scylla-movement-fast.png b/v1.10/_static/img/mascots/scylla-movement-fast.png new file mode 100644 index 00000000000..956d1dd0e22 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-movement-fast.png differ diff --git a/v1.10/_static/img/mascots/scylla-movement.png b/v1.10/_static/img/mascots/scylla-movement.png new file mode 100644 index 00000000000..7ee2b043384 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-movement.png differ diff --git a/v1.10/_static/img/mascots/scylla-onpremise.png b/v1.10/_static/img/mascots/scylla-onpremise.png new file mode 100644 index 00000000000..3b2dc8f1a2c Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-onpremise.png differ diff --git a/v1.10/_static/img/mascots/scylla-opensource.svg b/v1.10/_static/img/mascots/scylla-opensource.svg new file mode 100644 index 00000000000..299e9cb9955 --- /dev/null +++ b/v1.10/_static/img/mascots/scylla-opensource.svg @@ -0,0 +1 @@ +Plan de travail 1 diff --git a/v1.10/_static/img/mascots/scylla-operator.svg b/v1.10/_static/img/mascots/scylla-operator.svg new file mode 100644 index 00000000000..655a450b2a4 --- /dev/null +++ b/v1.10/_static/img/mascots/scylla-operator.svg @@ -0,0 +1 @@ +scylla-operator diff --git a/v1.10/_static/img/mascots/scylla-plugin.png b/v1.10/_static/img/mascots/scylla-plugin.png new file mode 100644 index 00000000000..b28dc857ccf Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-plugin.png differ diff --git a/v1.10/_static/img/mascots/scylla-release-mascot.png b/v1.10/_static/img/mascots/scylla-release-mascot.png new file mode 100644 index 00000000000..09342ac6875 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-release-mascot.png differ diff --git a/v1.10/_static/img/mascots/scylla-repair.png b/v1.10/_static/img/mascots/scylla-repair.png new file mode 100644 index 00000000000..9b4c613e702 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-repair.png differ diff --git a/v1.10/_static/img/mascots/scylla-server.png b/v1.10/_static/img/mascots/scylla-server.png new file mode 100644 index 00000000000..96dc785298b Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-server.png differ diff --git a/v1.10/_static/img/mascots/scylla-sleeping.png b/v1.10/_static/img/mascots/scylla-sleeping.png new file mode 100644 index 00000000000..f88598e05ad Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-sleeping.png differ diff --git a/v1.10/_static/img/mascots/scylla-tall-measure.png b/v1.10/_static/img/mascots/scylla-tall-measure.png new file mode 100644 index 00000000000..6f0ca146c0d Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-tall-measure.png differ diff --git a/v1.10/_static/img/mascots/scylla-university.png b/v1.10/_static/img/mascots/scylla-university.png new file mode 100644 index 00000000000..b3d0621193f Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-university.png differ diff --git a/v1.10/_static/img/mascots/scylla-weights.png b/v1.10/_static/img/mascots/scylla-weights.png new file mode 100644 index 00000000000..b070bb022cb Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-weights.png differ diff --git a/v1.10/_static/img/mascots/scylla-window-cleaning.png b/v1.10/_static/img/mascots/scylla-window-cleaning.png new file mode 100644 index 00000000000..6a8b16a6b4e Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-window-cleaning.png differ diff --git a/v1.10/_static/img/mascots/scylla-with-computer-2.png b/v1.10/_static/img/mascots/scylla-with-computer-2.png new file mode 100644 index 00000000000..f3b8b2984f6 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-with-computer-2.png differ diff --git a/v1.10/_static/img/mascots/scylla-with-computer.png b/v1.10/_static/img/mascots/scylla-with-computer.png new file mode 100644 index 00000000000..b38a6fbbe04 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-with-computer.png differ diff --git a/v1.10/_static/img/mascots/scylla-with-linux.png b/v1.10/_static/img/mascots/scylla-with-linux.png new file mode 100644 index 00000000000..954bf13bc29 Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-with-linux.png differ diff --git a/v1.10/_static/img/mascots/scylla-writting.png b/v1.10/_static/img/mascots/scylla-writting.png new file mode 100644 index 00000000000..d35a13d380d Binary files /dev/null and b/v1.10/_static/img/mascots/scylla-writting.png differ diff --git a/v1.10/_static/img/menu.svg b/v1.10/_static/img/menu.svg new file mode 100644 index 00000000000..30ea1d901e1 --- /dev/null +++ b/v1.10/_static/img/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.10/_static/js/main.bundle.js b/v1.10/_static/js/main.bundle.js new file mode 100644 index 00000000000..190a41642ef --- /dev/null +++ b/v1.10/_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 previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Contributing to Scylla Operator

          +
          +

          Prerequisites

          +

          To develop on scylla-operator, your environment must have the following:

          +
            +
          1. Go 1.13

            +
              +
            • Make sure GOPATH is set to GOPATH=$HOME/go.

            • +
            +
          2. +
          3. Kustomize v3.1.0

          4. +
          5. kubebuilder v2.3.1

          6. +
          7. Docker

          8. +
          9. Git client installed

          10. +
          11. Github account

          12. +
          +

          To install all dependencies (Go, kustomize, kubebuilder, dep), simply run:

          +
          ./install-dependencies.sh
          +
          +
          +
          +
          +

          Initial Setup

          +
          +

          Create a Fork

          +

          From your browser navigate to http://github.com/scylladb/scylla-operator and click the “Fork” button.

          +
          +
          +

          Clone Your Fork

          +

          Open a console window and do the following:

          +
          # Create the scylla operator repo path
          +mkdir -p $GOPATH/src/github.com/scylladb
          +
          +# Navigate to the local repo path and clone your fork
          +cd $GOPATH/src/github.com/scylladb
          +
          +# Clone your fork, where <user> is your GitHub account name
          +git clone https://github.com/<user>/scylla-operator.git
          +
          +
          +
          +
          +

          Add Upstream Remote

          +

          First you will need to add the upstream remote to your local git:

          +
          # Add 'upstream' to the list of remotes
          +git remote add upstream https://github.com/scylladb/scylla-operator.git
          +
          +# Verify the remote was added
          +git remote -v
          +
          +
          +

          Now you should have at least origin and upstream remotes. You can also add other remotes to collaborate with other contributors.

          +
          +
          +
          +

          Development

          +

          To add a feature or to make a bug fix, you will need to create a branch in your fork and then submit a pull request (PR) from the branch.

          +
          +

          Building the project

          +

          You can build the project using the Makefile commands:

          +
            +
          • Open the Makefile and change the IMG environment variable to a repository you have access to.

          • +
          • Run make docker-push and wait for the image to be built and uploaded in your repo.

          • +
          +
          +
          +

          Create a Branch

          +

          From a console, create a new branch based on your fork and start working on it:

          +
          # Ensure all your remotes are up to date with the latest
          +git fetch --all
          +
          +# Create a new branch that is based off upstream master.  Give it a simple, but descriptive name.
          +# Generally it will be two to three words separated by dashes and without numbers.
          +git checkout -b feature-name upstream/master
          +
          +
          +

          Now you are ready to make the changes and commit to your branch.

          +
          +
          +

          Updating Your Fork

          +

          During the development lifecycle, you will need to keep up-to-date with the latest upstream master. As others on the team push changes, you will need to rebase your commits on top of the latest. This avoids unnecessary merge commits and keeps the commit history clean.

          +

          Whenever you need to update your local repository, you never want to merge. You always will rebase. Otherwise you will end up with merge commits in the git history. If you have any modified files, you will first have to stash them (git stash save -u "<some description>").

          +
          git fetch --all
          +git rebase upstream/master
          +
          +
          +

          Rebasing is a very powerful feature of Git. You need to understand how it works or else you will risk losing your work. Read about it in the Git documentation, it will be well worth it. In a nutshell, rebasing does the following:

          +
            +
          • “Unwinds” your local commits. Your local commits are removed temporarily from the history.

          • +
          • The latest changes from upstream are added to the history

          • +
          • Your local commits are re-applied one by one

          • +
          • If there are merge conflicts, you will be prompted to fix them before continuing. Read the output closely. It will tell you how to complete the rebase.

          • +
          • When done rebasing, you will see all of your commits in the history.

          • +
          +
          +
          +
          +

          Submitting a Pull Request

          +

          Once you have implemented the feature or bug fix in your branch, you will open a PR to the upstream repo. Before opening the PR ensure you have added unit tests, are passing the integration tests, cleaned your commit history, and have rebased on the latest upstream.

          +

          In order to open a pull request (PR) it is required to be up to date with the latest changes upstream. If other commits are pushed upstream before your PR is merged, you will also need to rebase again before it will be merged.

          +
          +

          Commit History

          +

          To prepare your branch to open a PR, you will need to have the minimal number of logical commits so we can maintain +a clean commit history. Most commonly a PR will include a single commit where all changes are squashed, although +sometimes there will be multiple logical commits.

          +
          # Inspect your commit history to determine if you need to squash commits
          +git log
          +
          +# Rebase the commits and edit, squash, or even reorder them as you determine will keep the history clean.
          +# In this example, the last 5 commits will be opened in the git rebase tool.
          +git rebase -i HEAD~5
          +
          +
          +

          Once your commit history is clean, ensure you have based on the latest upstream before you open the PR.

          +
          +
          +

          Commit messages

          +

          Please make the first line of your commit message a summary of the change that a user (not a developer) of Operator would like to read, +and prefix it with the most relevant directory of the change followed by a colon. +The changelog gets made by looking at just these first lines so make it good!

          +

          If you have more to say about the commit, then enter a blank line and carry on the description. +Remember to say why the change was needed - the commit itself shows what was changed.

          +

          Writing more is better than less. Comparing the behaviour before the change to that after the change is very useful. +Imagine you are writing to yourself in 12 months time when you’ve forgotten everything about what you just did, and you need to get up to speed quickly.

          +

          If the change fixes an issue then write Fixes #1234 in the commit message. +This can be on the subject line if it will fit. If you don’t want to close the associated issue just put #1234 and the change will get linked into the issue.

          +

          Here is an example of a short commit message:

          +
          sidecar: log on reconcile loop - fixes #1234
          +
          +
          +

          And here is an example of a longer one:

          +
          
          +api: now supports host networking (#1234)
          +
          +The operator CRD now has a "network" property that can be used to
          +select host networking as well as setting the apropriate DNS policy.
          +
          +Fixes #1234
          +
          +
          +
          +
          +

          Submitting

          +

          Go to the Scylla Operator github to open the PR. If you have pushed recently, you should see an obvious link to open the PR. If you have not pushed recently, go to the Pull Request tab and select your fork and branch for the PR.

          +

          After the PR is open, you can make changes simply by pushing new commits. Your PR will track the changes in your fork and update automatically.

          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/eks.html b/v1.10/eks.html new file mode 100644 index 00000000000..750ea360dd3 --- /dev/null +++ b/v1.10/eks.html @@ -0,0 +1,716 @@ + + + + + + + + + + + + + Deploying Scylla on EKS | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Deploying Scylla on EKS

          +

          This guide is focused on deploying Scylla on EKS with improved performance. +Performance tricks used by the script won’t work with different machine tiers. +It sets up the kubelets on EKS nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

          +

          Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

          +
          +

          TL;DR;

          +

          If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

          +
          # Edit according to your preference
          +EKS_REGION=us-east-1
          +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
          +
          +# From inside the examples/eks folder
          +cd examples/eks
          +./eks.sh -z "$EKS_ZONES" -r "$EKS_REGION"
          +
          +
          +

          After you deploy, see how you can benchmark your cluster with cassandra-stress.

          +
          +
          +

          Walkthrough

          +
          +

          EKS Setup

          +
          +

          Configure environment variables

          +

          First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

          +
          EKS_REGION=us-east-1
          +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
          +CLUSTER_NAME=scylla-demo
          +
          +
          +
          +
          +

          Creating an EKS cluster

          +

          For this guide, we’ll create an EKS cluster with the following:

          +
            +
          • A NodeGroup of 3 i3-2xlarge Nodes, where the Scylla Pods will be deployed. These nodes will only accept pods having scylla-clusters toleration.

          • +
          +
            - name: scylla-pool
          +    instanceType: i3.2xlarge
          +    desiredCapacity: 3
          +    labels:
          +      scylla.scylladb.com/node-type: scylla
          +    taints:
          +      role: "scylla-clusters:NoSchedule"
          +    ssh:
          +      allow: true
          +    kubeletExtraConfig:
          +      cpuManagerPolicy: static
          +
          +
          +
            +
          • A NodeGroup of 4 c4.2xlarge Nodes to deploy cassandra-stress later on. These nodes will only accept pods having cassandra-stress toleration.

          • +
          +
            - name: cassandra-stress-pool
          +    instanceType: c4.2xlarge
          +    desiredCapacity: 4
          +    labels:
          +      pool: "cassandra-stress-pool"
          +    taints:
          +      role: "cassandra-stress:NoSchedule"
          +    ssh:
          +      allow: true
          +
          +
          +
            +
          • A NodeGroup of 1 i3.large Node, where the monitoring stack and operator will be deployed.

          • +
          +
            - name: monitoring-pool
          +    instanceType: i3.large
          +    desiredCapacity: 1
          +    labels:
          +      pool: "monitoring-pool"
          +    ssh:
          +      allow: true
          +
          +
          +
          +
          +
          +

          Prerequisites

          +
          +

          Installing script third party dependencies

          +

          Script requires several dependencies:

          +
            +
          • eksctl - See: https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html

          • +
          • kubectl - See: https://kubernetes.io/docs/tasks/tools/install-kubectl/

          • +
          +
          +
          +

          Setting up nodes for ScyllaDB

          +

          ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you’ll first need to form a RAID array from those disks. +NodeConfig performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in Performance tuning section of ScyllaDB Operator’s documentation.

          +

          Deploy NodeConfig to let it take care of the above operations:

          +
          kubectl apply --server-side -f examples/gke/nodeconfig-alpha.yaml
          +
          +
          +
          +
          +

          Deploying Local Volume Provisioner

          +

          Afterwards, deploy ScyllaDB’s Local Volume Provisioner, capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays.

          +
          kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/
          +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml
          +
          +
          +
          +
          +
          +

          Installing the Scylla Operator and Scylla

          +

          Now you can follow the generic guide to launch your Scylla cluster in a highly performant environment.

          +
          +

          Accessing the database

          +

          Instructions on how to access the database can also be found in the generic guide.

          +
          +
          +
          +

          Deleting an EKS cluster

          +

          Once you are done with your experiments delete your cluster using the following command:

          +
          eksctl delete cluster "${CLUSTER_NAME}"
          +
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/generic.html b/v1.10/generic.html new file mode 100644 index 00000000000..5a8b9e4c186 --- /dev/null +++ b/v1.10/generic.html @@ -0,0 +1,937 @@ + + + + + + + + + + + + + Deploying Scylla on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Deploying Scylla on a Kubernetes Cluster

          +

          This is a guide to deploy a Scylla Cluster in a generic Kubernetes environment, meaning that Scylla will not be deployed with the ideal performance. +Scylla performs the best when it has fast disks and direct access to the cpu. +This requires some extra setup, which is platform-specific. +For specific configuration and setup, check for details about your particular environment:

          + +
          +

          Prerequisites

          + +
          +
          +

          Running locally

          +

          Running kubernetes locally is a daunting and error prone task. +Fortunately there are ways to make life easier and Minikube makes it a breeze.

          +

          We need to give minikube a little bit more resources than default so start minikube like this:

          +
          minikube start --cpus=6
          +
          +
          +

          Then make kubectl aware of this local installation like this:

          +
          eval $(minikube docker-env)
          +
          +
          +
          +
          +

          Download Scylla Operator

          +

          In this guide you will be using the examples and manifests from Scylla Operator repository, so start off by cloning it to your local machine.

          +
          git clone git@github.com:scylladb/scylla-operator.git
          +cd scylla-operator
          +
          +
          +
          +
          +

          Deploy Cert Manager

          +

          First deploy Cert Manager, you can either follow upsteam instructions or use following command:

          +
          kubectl apply -f examples/common/cert-manager.yaml
          +
          +
          +

          This will install Cert Manager to provision a self-signed certificate.

          +

          Once it’s deployed, wait until Cert Manager is ready:

          +
          kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io
          +kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook
          +
          +
          +
          +
          +

          Deploy Scylla Operator

          +

          Deploy the Scylla Operator using the following commands:

          +
          kubectl apply -f examples/common/operator.yaml
          +
          +
          +

          This will install the operator in namespace scylla-operator. +Wait until it’s ready:

          +
          kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
          +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
          +
          +
          +

          If you want to check the logs of the operator you can do so with:

          +
          kubectl -n scylla-operator logs deployment.apps/scylla-operator
          +
          +
          +
          +
          +

          Create and Initialize a Scylla Cluster

          +

          Now that the operator is running, we can create an instance of a Scylla cluster by creating an instance of the clusters.scylla.scylladb.com resource. +Some of that resource’s values are configurable, so feel free to browse cluster.yaml and tweak the settings to your liking. +Full details for all the configuration options can be found in the Scylla Cluster CRD documentation.

          +

          When you are ready to create a Scylla cluster, simply run:

          +
          kubectl create -f examples/generic/cluster.yaml
          +
          +
          +

          We can verify that a Kubernetes object has been created that represents our new Scylla cluster with the command below. +This is important because it shows that has successfully extended Kubernetes to make Scylla clusters a first class citizen in the Kubernetes cloud-native environment.

          +
          kubectl -n scylla get ScyllaCluster
          +
          +
          +

          Checking the pods that are created is as easy as:

          +
          kubectl -n scylla get pods
          +
          +
          +

          The output should be something like:

          +
          NAME                                    READY   STATUS    RESTARTS   AGE
          +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          9m49s
          +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          7m43s
          +simple-cluster-us-east-1-us-east-1a-2   2/2     Running   0          6m46s
          +
          +
          +

          It is important to note that the operator creates these instances according to a pattern. +This pattern is as follows: CLUSTER_NAME-DATACENTER_NAME-RACK_NAME-INSTANCE_NUMBER as specified in cluster.yaml.

          +

          In the above example we have the following properties:

          +
            +
          • CLUSTER_NAME: simple-cluster

          • +
          • DATACENTER_NAME: us-east-1

          • +
          • RACK_NAME: us-east-1a

          • +
          • INSTANCE_NUMBER: An automatically generated number attached to the pod name.

          • +
          +

          We picked the names to resemble something you can find in a cloud service but this is inconsequential, they can be set to anything you want.

          +

          To check if all the desired members are running, you should see the same number of entries from the following command as the number of members that was specified in cluster.yaml:

          +
          kubectl -n scylla get pod -l app=scylla
          +
          +
          +

          You can also track the state of a Scylla cluster from its status. To check the current status of a Cluster, run:

          +
          kubectl -n scylla describe ScyllaCluster simple-cluster
          +
          +
          +

          Checking the logs of the running scylla instances can be done like this:

          +
          kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 scylla
          +
          +
          +
          +

          Configure host networking

          +

          To squeeze the most out of your deployment it is sometimes necessary to employ host networking. +To enable this the CRD allows for specifying a network parameter as such:

          +
          version: 4.0.0
          +  agentVersion: 2.0.2
          +  cpuset: true
          +  network:
          +    hostNetworking: true
          +
          +
          +

          This will result in hosts network to be used for the Scylla Stateful Set deployment.

          +
          +
          +

          Configure container kernel parameters

          +

          Sometimes it is necessary to run the container with different kernel parameters. +In order to support this, the Scylla Operator defines a cluster property sysctls that is a list of the desired key-value pairs to set.

          +

          For example: To increase the number events available for asynchronous IO processing in the Linux kernel to N set sysctls tofs.aio-max-nr=N.

          +
          spec:
          +  sysctls:
          +  - "fs.aio-max-nr=2097152"
          +
          +
          +
          +
          +

          Deploying Alternator

          +

          The operator is also capable of deploying Alternator instead of the regular Scylla. +This requires a small change in the cluster definition. +Change the cluster.yaml file from this:

          +
          spec:
          +  version: 4.0.0
          +  agentVersion: 2.0.2
          +  developerMode: true
          +  datacenter:
          +    name: us-east-1
          +
          +
          +

          to this:

          +
          spec:
          +  version: 4.0.0
          +  alternator:
          +    port: 8000
          +    writeIsolation: only_rmw_uses_lwt
          +  agentVersion: 2.0.2
          +  developerMode: true
          +  datacenter:
          +    name: us-east-1
          +
          +
          +

          You can specify whichever port you want.

          +

          You must provide desired write isolation, supported values are: “always”, “forbid_rmw”, “only_rmw_uses_lwt”. +Difference between those isolation levels can be found in Scylla Alternator documentation.

          +

          Once this is done the regular CQL ports will no longer be available, the cluster is a pure Alienator cluster.

          +
          +
          +
          +

          Accessing the Database

          +
            +
          • From kubectl:

          • +
          +

          To get a cqlsh shell in your new Cluster:

          +
          kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- cqlsh
          +> DESCRIBE KEYSPACES;
          +
          +
          +
            +
          • From inside a Pod:

          • +
          +

          When you create a new Cluster, automatically creates a Service for the clients to use in order to access the Cluster. +The service’s name follows the convention <cluster-name>-client. +You can see this Service in your cluster by running:

          +
          kubectl -n scylla describe service simple-cluster-client
          +
          +
          +

          Pods running inside the Kubernetes cluster can use this Service to connect to Scylla. +Here’s an example using the Python Driver:

          +
          from cassandra.cluster import Cluster
          +
          +cluster = Cluster(['simple-cluster-client.scylla.svc'])
          +session = cluster.connect()
          +
          +
          +

          If you are running the Alternator you can access the API on the port you specified using plain http.

          +
          +
          +

          Configure Scylla

          +

          The operator can take a ConfigMap and apply it to the scylla.yaml configuration file. +This is done by adding a ConfigMap to Kubernetes and refering to this in the Rack specification. +The ConfigMap is just a file called scylla.yaml that has the properties you want to change in it. +The operator will take the default properties for the rest of the configuration.

          +
            +
          • Create a ConfigMap the default name that the operator uses is scylla-config:

          • +
          +
          kubectl create configmap scylla-config -n scylla --from-file=/path/to/scylla.yaml
          +
          +
          +
            +
          • Wait for the mount to propagate and then restart the cluster:

          • +
          +
          kubectl rollout restart -n scylla statefulset/simple-cluster-us-east-1-us-east-1a
          +
          +
          +
            +
          • The new config should be applied automatically by the operator, check the logs to be sure.

          • +
          +

          Configuring cassandra-rackdc.properties is done by adding the file to the same mount as scylla.yaml.

          +
          kubectl create configmap scylla-config -n scylla --from-file=/tmp/scylla.yaml --from-file=/tmp/cassandra-rackdc.properties -o yaml --dry-run | kubectl replace -f -
          +
          +
          +

          The operator will then apply the overridable properties prefer_local and dc_suffix if they are available in the provided mounted file.

          +
          +
          +

          Configure Scylla Manager Agent

          +

          The operator creates a second container for each scylla instance that runs Scylla Manager Agent. +This container serves as a sidecar and it’s the main endpoint for interacting with Scylla API. +The Scylla Manager Agent can be configured with various things such as the security token used to allow access to Scylla API and storage providers for backups.

          +

          To configure the agent you just create a new secret called scylla-agent-config-secret and populate it with the contents in the scylla-manager-agent.yaml file like this:

          +
          kubectl create secret -n scylla generic scylla-agent-config-secret --from-file scylla-manager-agent.yaml
          +
          +
          +

          See Scylla Manager Agent configuration for a complete reference of the Scylla Manager agent config file.

          +
          +

          Scylla Manager Agent auth token

          +

          Operator provisions Agent auth token by copying value from user provided config secret or auto generates it if it’s empty. +To check which value is being used, decode content of <cluster-name>-auth-token secret. +To change it simply remove the secret. Operator will create a new one. To pick up the change in the cluster, initiate a rolling restart.

          +
          +
          +
          +

          Set up monitoring

          +

          To set up monitoring using Prometheus and Grafana follow this guide.

          +
          +
          +

          Scale Up

          +

          The operator supports scale up of a rack as well as addition of new racks. To make the changes, you can use:

          +
          kubectl -n scylla edit ScyllaCluster simple-cluster
          +
          +
          +
            +
          • To scale up a rack, change the Spec.Members field of the rack to the desired value.

          • +
          • To add a new rack, append the racks list with a new rack. Remember to choose a different rack name for the new rack.

          • +
          • After editing and saving the yaml, check your cluster’s Status and Events for information on what’s happening:

          • +
          +
          kubectl -n scylla describe ScyllaCluster simple-cluster
          +
          +
          +
          +
          +

          Benchmark with cassandra-stress

          +

          After deploying our cluster along with the monitoring, we can benchmark it using cassandra-stress and see its performance in Grafana. We have a mini cli that generates Kubernetes Jobs that run cassandra-stress against a cluster.

          +
          +

          Because cassandra-stress doesn’t scale well to multiple cores, we use multiple jobs with a small core count for each

          +
          +
          # Run a benchmark with 10 jobs, with 6 cpus and 50.000.000 operations each.
          +# Each Job will throttle throughput to 30.000 ops/sec for a total of 300.000 ops/sec.
          +hack/cass-stress-gen.py --num-jobs=10 --cpu=6 --memory=20G --ops=50000000 --limit=30000
          +kubectl apply -f scripts/cassandra-stress.yaml
          +
          +
          +

          Make sure you set the proper arguments in case you have altered things such as name or namespace.

          +
          ./hack/cass-stress-gen.py -h
          +usage: cass-stress-gen.py [-h] [--num-jobs NUM_JOBS] [--name NAME] [--namespace NAMESPACE] [--scylla-version SCYLLA_VERSION] [--host HOST] [--cpu CPU] [--memory MEMORY] [--ops OPS] [--threads THREADS] [--limit LIMIT]
          +                          [--connections-per-host CONNECTIONS_PER_HOST] [--print-to-stdout] [--nodeselector NODESELECTOR]
          +
          +Generate cassandra-stress job templates for Kubernetes.
          +
          +optional arguments:
          +  -h, --help            show this help message and exit
          +  --num-jobs NUM_JOBS   number of Kubernetes jobs to generate - defaults to 1
          +  --name NAME           name of the generated yaml file - defaults to cassandra-stress
          +  --namespace NAMESPACE
          +                        namespace of the cassandra-stress jobs - defaults to "default"
          +  --scylla-version SCYLLA_VERSION
          +                        version of scylla server to use for cassandra-stress - defaults to 4.0.0
          +  --host HOST           ip or dns name of host to connect to - defaults to scylla-cluster-client.scylla.svc
          +  --cpu CPU             number of cpus that will be used for each job - defaults to 1
          +  --memory MEMORY       memory that will be used for each job in GB, ie 2G - defaults to 2G * cpu
          +  --ops OPS             number of operations for each job - defaults to 10000000
          +  --threads THREADS     number of threads used for each job - defaults to 50 * cpu
          +  --limit LIMIT         rate limit for each job - defaults to no rate-limiting
          +  --connections-per-host CONNECTIONS_PER_HOST
          +                        number of connections per host - defaults to number of cpus
          +  --print-to-stdout     print to stdout instead of writing to a file
          +  --nodeselector NODESELECTOR
          +                        nodeselector limits cassandra-stress pods to certain nodes. Use as a label selector, eg. --nodeselector role=scylla
          +
          +
          +

          While the benchmark is running, open up Grafana and take a look at the monitoring metrics.

          +

          After the Jobs finish, clean them up with:

          +
          kubectl delete -f scripts/cassandra-stress.yaml
          +
          +
          +
          +
          +

          Scale Down

          +

          The operator supports scale down of a rack. To make the changes, you can use:

          +
          kubectl -n scylla edit ScyllaCluster simple-cluster
          +
          +
          +
            +
          • To scale down a rack, change the Spec.Members field of the rack to the desired value.

          • +
          • After editing and saving the yaml, check your cluster’s Status and Events for information on what’s happening:

          • +
          +
          kubectl -n scylla describe ScyllaCluster simple-cluster
          +
          +
          +
          +
          +

          Clean Up

          +

          To clean up all resources associated with this walk-through, you can run the commands below.

          +

          NOTE: this will destroy your database and delete all of its associated data.

          +
          kubectl delete -f examples/generic/cluster.yaml
          +kubectl delete -f examples/common/operator.yaml
          +kubectl delete -f examples/common/cert-manager.yaml
          +
          +
          +
          +
          +

          Troubleshooting

          +

          If the cluster does not come up, the first step would be to examine the operator’s logs:

          +
          kubectl -n scylla-operator logs deployment.apps/scylla-operator
          +
          +
          +

          If everything looks OK in the operator logs, you can also look in the logs for one of the Scylla instances:

          +
          kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/genindex.html b/v1.10/genindex.html new file mode 100644 index 00000000000..1d579718792 --- /dev/null +++ b/v1.10/genindex.html @@ -0,0 +1,543 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + + + +
          + + + + + +
          + + +
          + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/gke.html b/v1.10/gke.html new file mode 100644 index 00000000000..6b29c2d532c --- /dev/null +++ b/v1.10/gke.html @@ -0,0 +1,754 @@ + + + + + + + + + + + + + Deploying Scylla on GKE | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Deploying Scylla on GKE

          +

          This guide is focused on deploying Scylla on GKE with maximum performance (without any persistence guarantees). +It sets up the kubelets on GKE nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

          +

          Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

          +
          +

          TL;DR;

          +

          If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

          +
          # Edit according to your preference
          +GCP_USER=$(gcloud config list account --format "value(core.account)")
          +GCP_PROJECT=$(gcloud config list project --format "value(core.project)")
          +GCP_ZONE=us-west1-b
          +
          +# From inside the examples/gke folder
          +cd examples/gke
          +./gke.sh -u "$GCP_USER" -p "$GCP_PROJECT" -z "$GCP_ZONE"
          +
          +# Example:
          +# ./gke.sh -u yanniszark@arrikto.com -p gke-demo-226716 -z us-west1-b
          +
          +
          +

          :warning: Make sure to pass a ZONE (ex.: us-west1-b) and not a REGION (ex.: us-west1) or it will deploy nodes in each ZONE available in the region.

          +

          After you deploy, see how you can benchmark your cluster with cassandra-stress.

          +
          +
          +

          Walkthrough

          +
          +

          Google Kubernetes Engine Setup

          +
          +

          Configure environment variables

          +

          First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

          +
          GCP_USER=$( gcloud config list account --format "value(core.account)" )
          +GCP_PROJECT=$( gcloud config list project --format "value(core.project)" )
          +GCP_REGION=us-west1
          +GCP_ZONE=us-west1-b
          +CLUSTER_NAME=scylla-demo
          +CLUSTER_VERSION=$( gcloud container get-server-config --zone ${GCP_ZONE} --format "value(validMasterVersions[0])" )
          +
          +
          +
          +
          +

          Creating a GKE cluster

          +

          First we need to change kubelet CPU Manager policy to static by providing a config file. Create file called systemconfig.yaml with the following content:

          +
          kubeletConfig:
          +  cpuManagerPolicy: static
          +
          +
          +

          Then we’ll create a GKE cluster with the following:

          +
            +
          1. A NodePool of 2 n1-standard-8 Nodes, where the operator and the monitoring stack will be deployed. These are generic Nodes and their free capacity can be used for other purposes.

            +
            gcloud container \
            +clusters create "${CLUSTER_NAME}" \
            +--cluster-version "${CLUSTER_VERSION}" \
            +--node-version "${CLUSTER_VERSION}" \
            +--machine-type "n1-standard-8" \
            +--num-nodes "2" \
            +--disk-type "pd-ssd" --disk-size "20" \
            +--image-type "UBUNTU_CONTAINERD" \
            +--system-config-from-file=systemconfig.yaml \
            +--enable-stackdriver-kubernetes \
            +--no-enable-autoupgrade \
            +--no-enable-autorepair
            +
            +
            +
          2. +
          3. A NodePool of 2 n1-standard-32 Nodes to deploy cassandra-stress later on.

            +
            gcloud container --project "${GCP_PROJECT}" \
            +node-pools create "cassandra-stress-pool" \
            +--cluster "${CLUSTER_NAME}" \
            +--zone "${GCP_ZONE}" \
            +--node-version "${CLUSTER_VERSION}" \
            +--machine-type "n1-standard-32" \
            +--num-nodes "2" \
            +--disk-type "pd-ssd" --disk-size "20" \
            +--node-taints role=cassandra-stress:NoSchedule \
            +--image-type "UBUNTU_CONTAINERD" \
            +--no-enable-autoupgrade \
            +--no-enable-autorepair
            +
            +
            +
          4. +
          5. A NodePool of 4 n1-standard-32 Nodes, where the Scylla Pods will be deployed. Each of these Nodes has 8 local NVMe SSDs attached, which are provided as raw block devices. It is important to disable autoupgrade and autorepair. Automatic cluster upgrade or node repair has a hard timeout after which it no longer respect PDBs and force deletes the Compute Engine instances, which also deletes all data on the local SSDs. At this point, it’s better to handle upgrades manually, with more control over the process and error handling.

            +
            gcloud container \
            +node-pools create "scylla-pool" \
            +--cluster "${CLUSTER_NAME}" \
            +--node-version "${CLUSTER_VERSION}" \
            +--machine-type "n1-standard-32" \
            +--num-nodes "4" \
            +--disk-type "pd-ssd" --disk-size "20" \
            +--local-nvme-ssd-block count="8" \
            +--node-taints role=scylla-clusters:NoSchedule \
            +--node-labels scylla.scylladb.com/node-type=scylla \
            +--image-type "UBUNTU_CONTAINERD" \
            +--no-enable-autoupgrade \
            +--no-enable-autorepair
            +
            +
            +
          6. +
          +
          +
          +

          Setting Yourself as cluster-admin

          +
          +

          (By default GKE doesn’t give you the necessary RBAC permissions)

          +
          +

          Get the credentials for your new cluster

          +
          gcloud container clusters get-credentials "${CLUSTER_NAME}" --zone="${GCP_ZONE}"
          +
          +
          +

          Create a ClusterRoleBinding for your user. +In order for this to work you need to have at least permission container.clusterRoleBindings.create. +The easiest way to obtain this permission is to enable the Kubernetes Engine Admin role for your user in the GCP IAM web interface.

          +
          kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user "${GCP_USER}"
          +
          +
          +
          +
          +
          +

          Prerequisites

          +
          +

          Setting up nodes for ScyllaDB

          +

          ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you’ll first need to form a RAID array from those disks. +NodeConfig performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in Performance tuning section of ScyllaDB Operator’s documentation.

          +

          Deploy NodeConfig to let it take care of the above operations:

          +
          kubectl apply --server-side -f examples/gke/nodeconfig-alpha.yaml
          +
          +
          +
          +
          +

          Deploying Local Volume Provisioner

          +

          Afterwards, deploy ScyllaDB’s Local Volume Provisioner, capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays.

          +
          kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/
          +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml
          +
          +
          +
          +
          +
          +

          Deploy Scylla cluster

          +

          In order for the example to work you need to modify the cluster definition in the following way:

          +
          sed -i "s/<gcp_region>/${GCP_REGION}/g;s/<gcp_zone>/${GCP_ZONE}/g" examples/gke/cluster.yaml
          +
          +
          +

          This will inject your region and zone into the cluster definition so that it matches the kubernetes cluster you just created.

          +
          +
          +

          Installing the Scylla Operator and Scylla

          +

          Now you can follow the generic guide to install the operator and launch your Scylla cluster in a highly performant environment.

          +
          +

          Accessing the database

          +

          Instructions on how to access the database can also be found in the generic guide.

          +
          +
          +
          +

          Deleting a GKE cluster

          +

          Once you are done with your experiments delete your cluster using the following command:

          +
          gcloud container --project "${GCP_PROJECT}" clusters delete --zone "${GCP_ZONE}" "${CLUSTER_NAME}"
          +
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/helm.html b/v1.10/helm.html new file mode 100644 index 00000000000..7b1b914597c --- /dev/null +++ b/v1.10/helm.html @@ -0,0 +1,910 @@ + + + + + + + + + + + + + Deploying Scylla stack using Helm Charts | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Deploying Scylla stack using Helm Charts

          +

          In this example we will install Scylla stack on Kubernetes. This includes the following components:

          +
            +
          • Scylla Operator

          • +
          • Scylla Manager

          • +
          • Scylla

          • +
          +

          We will use Minikube K8s cluster, but this could be any K8s cluster supported by the Scylla Operator.

          +
          +

          Prerequisites

          +
            +
          • Kubernetes 1.16+

          • +
          • Helm 3+

          • +
          +
          +
          +

          TL;DR

          +
          helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
          +helm repo update
          +kubectl apply -f examples/common/cert-manager.yaml 
          +helm install scylla-operator scylla/scylla-operator --create-namespace --namespace scylla-operator
          +helm install scylla-manager scylla/scylla-manager --create-namespace --namespace scylla-manager
          +helm install scylla scylla/scylla --create-namespace --namespace scylla
          +
          +
          +
          +
          +

          Deploy Cert Manager

          +

          This step is optional if you want to use your own certificate. +If you don’t have one, make sure to not disable autogeneration using Scylla Operator Helm Chart.

          +

          First deploy Cert Manager, you can either follow upsteam instructions or use following command:

          +
          kubectl apply -f examples/common/cert-manager.yaml
          +
          +
          +

          Once it’s deployed, wait until all Cert Manager pods will enter into Running state:

          +
          kubectl wait -n cert-manager --for=condition=ready pod -l app=cert-manager --timeout=60s
          +
          +
          +
          +
          +

          Helm Chart repository

          +

          To install Scylla Helm Chart repository execute the following commands:

          +
          helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
          +helm repo update
          +
          +
          +

          Then you can search through repository, it should contain at least three Helm charts:

          +
          helm search repo scylla
          +NAME                   CHART VERSION   APP VERSION     DESCRIPTION                                       
          +scylla/scylla          1.0.1           v1.0.1          Scylla is a close-to-the-hardware rewrite of Ca...
          +scylla/scylla-manager  1.0.1           v1.0.1          Scylla Manager automates database operations.     
          +scylla/scylla-operator 1.0.1           v1.0.1          Scylla Operator is a Kubernetes Operator for ma...
          +
          +
          +

          All these charts should be installable without any need of customizing (defaults are provided). +Although Helm is used for this particular reason, so lets customize them a bit.

          +
          +
          +

          Scylla Operator Chart

          +

          This chart is very simple, most interesting customizable fields are image, resources and webhook. +All others can be looked up in Chart source in Scylla Operator repository.

          +
          +

          image

          +

          Image allows to define which Scylla Operator image will be used. By default it downloads the image from main +Docker Hub repository, using version defined in Helm Chart. +You can also change pullPolicy if default one does not +fullfill your needs. In Kubernetes documentation you +can read more about different pull policies.

          +

          Image URL will be composed based on these fields in follwing pattern: +repository/scylla-operator:tag

          +
          image:
          +  repository: scylladb
          +  pullPolicy: IfNotPresent
          +  tag: ""
          +
          +
          +
          +
          +

          resources

          +

          You can customize how much resources will be allocated for Operator pods via resource field:

          +
          resources:
          +  limits:
          +    cpu: 100m
          +    memory: 128Mi
          +  requests:
          +    cpu: 100m
          +    memory: 32Mi
          +
          +
          +

          To read more about resource specification, follow Kubernetes documentation.

          +
          +
          +

          webhook

          +

          Webhook field allows to decide whether you want to use autogenerated self-signed certificate using Cert Manager or +whether you want to provide your own certificate.

          +

          createSelfSignedCertificate specifies whether a self-signed certificate should be created using Cert Manager +certificateSecretName: name of a secret containing custom certificate.

          +
          webhook:
          +  createSelfSignedCertificate: true
          +  certificateSecretName: ""
          +
          +
          +
          +
          +

          Customization

          +

          You can customize all these fields and others by providing file containing desired values. +Content of this file will overwrite default values.

          +

          You can find an example in Scylla Operator repository under examples/helm/values.operator.yaml

          +
          +
          +

          Installation

          +

          To deploy Scylla Operator using customized values file execute the following:

          +
          helm install scylla-operator scylla/scylla-operator --values examples/helm/values.operator.yaml --create-namespace --namespace scylla-operator
          +
          +
          +
          +
          +
          +

          Scylla Helm Chart

          +

          Scylla Chart allows to customize and deploy Scylla cluster. +By default Scylla Helm charts deploys working Scylla cluster, but of course we can customize it.

          +
          +

          Customization

          +

          Versions of images used in the cluster can be set via scyllaImage and agentImage

          +
          scyllaImage:
          +  repository: scylladb/scylla
          +  tag: 4.3.0
          +
          +agentImage:
          +  repository: scylladb/scylla-manager-agent
          +  tag: 2.2.1
          +
          +
          +

          A minimal Scylla cluster can be expressed as:

          +
          datacenter: us-east-1
          +racks:
          +- name: us-east-1b
          +  members: 2
          +  storage:
          +    capacity: 5G
          +  resources:
          +    limits:
          +      cpu: 1
          +      memory: 1Gi
          +    requests:
          +      cpu: 1
          +      memory: 1Gi
          +
          +
          +

          Above cluster will use 4.3.0 Scylla, 2.2.1 Scylla Manager Agent sidecar and will have a single rack having 2 nodes. +Each node will have a single CPU and 1 GiB of memory.

          +

          For other customizable fields, please refer to ScyllaCluster CRD definition. +CRD Rack Spec and Helm Chart Rack should have the same fields.

          +
          +
          +

          Installation

          +

          To deploy Scylla cluster using customzied values file execute the following command:

          +
          helm install scylla scylla/scylla --values examples/helm/values.cluster.yaml --create-namespace --namespace scylla
          +
          +
          +

          Scylla Operator will provision this cluster on your K8s environment.

          +
          +
          +
          +

          Scylla Manager Helm Chart

          +

          Scylla Manager Chart allows to customize and deploy Scylla Manager in K8s environment. +Scylla Manager consist of two applications (Scylla Manager itself and Scylla Manager Controller) and additional Scylla cluster.

          +

          To read more about Scylla Manager see Manager guide.

          +
          +

          Scylla Manager

          +

          To set version of used Scylla Manager you can use image field:

          +
          image:
          +  repository: scylladb
          +  pullPolicy: IfNotPresent
          +  tag: 2.2.1
          +
          +
          +

          To control how many resources are allocated for Scylla Manager use resource field:

          +
          resources:
          +  limits:
          +    cpu: 500m
          +    memory: 500Mi
          +  requests:
          +    cpu: 500m
          +    memory: 500Mi
          +
          +
          +
          +
          +

          Scylla Manager Controller

          +

          Similarly Scylla Manager Controller image can be customized:

          +
          controllerImage:
          +  repository: scylladb
          +  pullPolicy: IfNotPresent
          +  tag: ""
          +
          +
          +

          And allocated resources:

          +
          controllerResources:
          +  limits:
          +    cpu: 100m
          +    memory: 30Mi
          +  requests:
          +    cpu: 100m
          +    memory: 20Mi
          +
          +
          +
          +
          +

          Scylla

          +

          To customize internal Scylla instance dedicated to Scylla Manager, see guide above customizing Scylla Helm Chart. +It’s definition should land as a scylla field.

          +
          +
          +

          Customization

          +

          All others customizable fields can be looked up in Chart source in Scylla Operator repository.

          +
          +
          +

          Installation

          +

          To deploy Scylla Manager using customized values file execute the following command:

          +
          helm install scylla-manager scylla/scylla-manager --values examples/helm/values.manager.yaml --create-namespace --namespace scylla-manager
          +
          +
          +
          +
          +
          +

          Results

          +

          Scylla need some time to bootstrap all nodes, but after some time you should be ready to roll. It was simple isn’t it? +You can validate if everything was set up correctly by looking at the all resources created in used namespaces.

          +

          Scylla Operator:

          +
          $ kubectl -n scylla-operator get all
          +
          +NAME                                   READY   STATUS    RESTARTS   AGE
          +pod/scylla-operator-5dbcb54f5c-vjm4m   1/1     Running   0          51s
          +pod/scylla-operator-5dbcb54f5c-wfjbw   1/1     Running   0          51s
          +
          +NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
          +service/scylla-operator-webhook   ClusterIP   10.105.207.130   <none>        443/TCP   51s
          +
          +NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
          +deployment.apps/scylla-operator   2/2     2            2           51s
          +
          +NAME                                         DESIRED   CURRENT   READY   AGE
          +replicaset.apps/scylla-operator-5dbcb54f5c   2         2         2       51s
          +
          +
          +

          Operator is running!

          +

          Scylla Manager:

          +
          $ kubectl -n scylla-manager get all 
          +
          +NAME                                             READY   STATUS    RESTARTS   AGE
          +pod/scylla-manager-669db64dd-bcm4v               1/1     Running   0          89s
          +pod/scylla-manager-controller-844ccc56c4-drbth   1/1     Running   0          89s
          +pod/scylla-manager-controller-844ccc56c4-rhwqx   1/1     Running   0          89s
          +
          +NAME                            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
          +service/scylla-manager          ClusterIP   10.105.231.53   <none>        80/TCP,5090/TCP     89s
          +service/scylla-manager-client   ClusterIP   None            <none>        9180/TCP,5090/TCP   89s
          +
          +NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
          +deployment.apps/scylla-manager              1/1     1            1           89s
          +deployment.apps/scylla-manager-controller   2/2     2            2           89s
          +
          +NAME                                                   DESIRED   CURRENT   READY   AGE
          +replicaset.apps/scylla-manager-669db64dd               1         1         1       89s
          +replicaset.apps/scylla-manager-controller-844ccc56c4   2         2         2       89s
          +
          +
          +

          Good to go, ready to serve!

          +

          Scylla itself:

          +
          $ kubectl -n scylla get all        
          +
          +NAME                                READY   STATUS    RESTARTS   AGE
          +pod/scylla-us-east-1-us-east-1b-0   2/2     Running   0          5m58s
          +pod/scylla-us-east-1-us-east-1b-1   2/2     Running   0          4m29s
          +
          +NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
          +service/scylla-client                   ClusterIP   None           <none>        9180/TCP,5090/TCP                                                 5m59s
          +service/scylla-us-east-1-us-east-1b-0   ClusterIP   10.43.149.92   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   5m58s
          +service/scylla-us-east-1-us-east-1b-1   ClusterIP   10.43.49.0     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   4m29s
          +
          +NAME                                           READY   AGE
          +statefulset.apps/scylla-us-east-1-us-east-1b   2/2     5m59s
          +
          +
          +

          Two running nodes, exactly what we were asking for.

          +
          +
          +

          Monitoring

          +

          To spin up a Prometheus monitoring refer to monitoring guide.

          +

          Helm charts can create ServiceMonitors needed to observe Scylla Managger and Scylla. +Both of these Helm Charts allows to specify whether you want to create a ServiceMonitor:

          +
          serviceMonitor:
          +  create: false
          +
          +
          +

          Change create to true and update your current deployment using:

          +
          helm upgrade --install scylla --namespace scylla scylla/scylla -f examples/helm/values.cluster.yaml
          +
          +
          +

          Helm should notice the difference, install the ServiceMonitor, and then Prometheous will be able to scrape metrics.

          +
          +
          +

          Cleanup

          +

          To remove these applications you can simply uninstall them using Helm CLI:

          +
          helm uninstall scylla -n scylla
          +helm uninstall scylla-manager -n scylla-manager
          +helm uninstall scylla-operator -n scylla-operator
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/index.html b/v1.10/index.html new file mode 100644 index 00000000000..13ba545ed9c --- /dev/null +++ b/v1.10/index.html @@ -0,0 +1,589 @@ + + + + + + + + + + + + + Scylla Operator Documentation | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Scylla Operator Documentation

          +
          +
          +

          Scylla Operator is an open source project which helps users of Scylla Open Source and Scylla Enterprise run Scylla on Kubernetes (K8s) +The Scylla operator manages Scylla clusters deployed to Kubernetes and automates tasks related to operating a Scylla cluster, like installation, out and downscale, rolling upgrades.

          +_images/logo.png +

          For the latest status of the project, and reports issue, see the Github Project. Also check out the K8s Operator lesson on Scylla University.

          +

          scylla-operator is a Kubernetes Operator for managing Scylla clusters.

          +

          Currently it supports:

          +
            +
          • Deploying multi-zone clusters

          • +
          • Scaling up or adding new racks

          • +
          • Scaling down

          • +
          • Monitoring with Prometheus and Grafana

          • +
          • Integration with Scylla Manager

          • +
          • Dead node replacement

          • +
          • Version Upgrade

          • +
          • Backup

          • +
          • Repairs

          • +
          • Autohealing

          • +
          • Monitoring with Prometheus and Grafana

          • +
          +

          Choose a topic to begin:

          + +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/known-issues.html b/v1.10/known-issues.html new file mode 100644 index 00000000000..8ab1bc7cfb4 --- /dev/null +++ b/v1.10/known-issues.html @@ -0,0 +1,586 @@ + + + + + + + + + + + + + Known issues | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Known issues

          +
          +

          Scylla Manager does not boot up on Minikube

          +

          If your Scylla Manager is failing to apply 8th migration (008_*), then apply fix for TRUNCATE queries.

          +
          +
          +

          TRUNCATE queries does not work on Minikube

          +

          The TRUNCATE queries requires hairpinning to be enabled. On minikube this is disabled by default.

          +

          To fix it execute the following command:

          +
          minikube ssh sudo ip link set docker0 promisc on
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/manager.html b/v1.10/manager.html new file mode 100644 index 00000000000..e7602b0c2f2 --- /dev/null +++ b/v1.10/manager.html @@ -0,0 +1,797 @@ + + + + + + + + + + + + + Deploying Scylla Manager on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Deploying Scylla Manager on a Kubernetes Cluster

          +

          Scylla Manager is a product for database operations automation, +it can schedule tasks such as repairs and backups. +Scylla Manager can manage multiple Scylla clusters and run cluster-wide tasks +in a controlled and predictable way.

          +

          Scylla Manager is available for Scylla Enterprise customers and Scylla Open Source users. +With Scylla Open Source, Scylla Manager is limited to 5 nodes. +See the Scylla Manager Proprietary Software License Agreement for details.

          +
          +

          Prerequisites

          + +
          +
          +

          Architecture

          +

          Scylla Manager in K8s consist of:

          +
            +
          • Dedicated Scylla Cluster

            +

            Scylla Manager persists its state to a Scylla cluster. +Additional small single node cluster is spawned in the Manager namespace.

            +
          • +
          • Scylla Manager Controller

            +

            Main mission of Controller is to watch changes of Scylla Clusters, and synchronize three states.

            +
              +
            1. What user wants - task definition in CRD.

            2. +
            3. What Controller registered - Task name to Task ID mapping - CRD status.

            4. +
            5. Scylla Manager task listing - internal state of Scylla Manager.

            6. +
            +

            When Scylla Cluster CRD is being deployed Controller will register it in Scylla Manager once cluster reaches desired node count. +Once Cluster is fully up and running it will schedule all tasks defined in Cluster CRD. +Controller also supports task updates and unscheduling.

            +
          • +
          • Scylla Manager

            +

            Regular Scylla Manager, the same used in cloud and bare metal deployments.

            +
          • +
          +
          +
          +

          Deploy Scylla Manager

          +

          Deploy the Scylla Manager using the following commands:

          +
          kubectl apply -f examples/common/manager.yaml
          +
          +
          +

          This will install the Scylla Manager in the scylla-manager namespace. +You can check if the Scylla Manager is up and running with:

          +
          kubectl -n scylla-manager get pods
          +NAME                                               READY   STATUS    RESTARTS   AGE
          +scylla-manager-cluster-manager-dc-manager-rack-0   2/2     Running   0          37m
          +scylla-manager-controller-0                        1/1     Running   0          28m
          +scylla-manager-scylla-manager-7bd9f968b9-w25jw     1/1     Running   0          37m
          +
          +
          +

          As you can see there are three pods:

          +
            +
          • scylla-manager-cluster-manager-dc-manager-rack-0 - is a single node Scylla cluster.

          • +
          • scylla-manager-controller-0 - Scylla Manager Controller.

          • +
          • scylla-manager-scylla-manager-7bd9f968b9-w25jw - Scylla Manager.

          • +
          +

          To see if Scylla Manager is fully up and running we can check their logs. +To do this, execute following command:

          +
          kubectl -n scylla-manager logs scylla-manager-controller-0
          +
          +
          +

          The output should be something like:

          +
          {"L":"INFO","T":"2020-09-23T11:25:27.882Z","M":"Scylla Manager Controller started","version":"","build_date":"","commit":"","built_by":"","go_version":"","options":{"Name":"scylla-manager-controller-0","Namespace":"scylla-manager","LogLevel":"debug","ApiAddress":"http://127.0.0.1:5080/api/v1"},"_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
          +{"L":"INFO","T":"2020-09-23T11:25:28.435Z","M":"Registering Components.","_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
          +
          +
          +

          To check logs of Scylla Manager itself, use following command:

          +
          kubectl -n scylla-manager logs scylla-manager-scylla-manager-7bd9f968b9-w25jw
          +
          +
          +

          The output should be something like:

          +
          {"L":"INFO","T":"2020-09-23T11:26:53.238Z","M":"Scylla Manager Server","version":"2.1.2-0.20200816.76cc4dcc","pid":1,"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
          +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Using config","config":{"HTTP":"127.0.0.1:5080","HTTPS":"","TLSCertFile":"/var/lib/scylla-manager/scylla_manager.crt","TLSKeyFile":"/var/lib/scylla-manager/scylla_manager.key","TLSCAFile":"","Prometheus":":56090","PrometheusScrapeInterval":5000000000,"debug":"127.0.0.1:56112","Logger":{"Mode":"stderr","Level":"info","Development":false},"Database":{"Hosts":["scylla-manager-cluster-manager-dc-manager-rack-0.scylla-manager.svc"],"SSL":false,"User":"","Password":"","LocalDC":"","Keyspace":"scylla_manager","MigrateDir":"/etc/scylla-manager/cql","MigrateTimeout":30000000000,"MigrateMaxWaitSchemaAgreement":300000000000,"ReplicationFactor":1,"Timeout":600000000,"TokenAware":true},"SSL":{"CertFile":"","Validate":true,"UserCertFile":"","UserKeyFile":""},"Healthcheck":{"Timeout":250000000,"SSLTimeout":750000000},"Backup":{"DiskSpaceFreeMinPercent":10,"AgeMax":43200000000000},"Repair":{"SegmentsPerRepair":1,"ShardParallelMax":0,"ShardFailedSegmentsMax":100,"PollInterval":200000000,"ErrorBackoff":300000000000,"AgeMax":0,"ShardingIgnoreMsbBits":12}},"config_files":["/mnt/etc/scylla-manager/scylla-manager.yaml"],"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
          +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Checking database connectivity...","_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
          +
          +
          +

          If there are no errors in the logs, let’s spin a Scylla Cluster.

          +
          +
          +

          Cluster registration

          +

          When the Scylla Manager is fully up and running, lets create a regular instance of Scylla cluster.

          +

          See generic tutorial to spawn your cluster.

          +

          Note: If you already have some Scylla Clusters, after installing Manager they should be +automatically registered in Scylla Manager.

          +

          Once cluster reaches desired node count, cluster status will be updated with ID under which it was registered in Manager.

          +
          kubectl -n scylla describe Cluster
          +
          +[...]
          +Status:
          + Manager Id:  d1d532cd-49f2-4c97-9263-25126532803b
          + Racks:
          +   us-east-1a:
          +     Members:        3
          +     Ready Members:  3
          +     Version:        4.0.0
          +
          +
          +

          You can use this ID to talk to Scylla Manager using sctool CLI installed in Scylla Manager Pod. +You can also use Cluster name in namespace/cluster-name format.

          +
          kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
          +
          +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
          +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
          +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
          +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
          +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
          +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
          +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
          +
          +
          +

          Scylla Manager by default registers recurring healhcheck tasks for Agent and for each of the enabled frontends (CQL, Alternator).

          +

          In this task listing we can see CQL and REST healthchecks.

          +
          +
          +

          Task scheduling

          +

          You can either define tasks prior Cluster creation, or for existing Cluster. +Let’s edit already running cluster definition to add repair and backup task.

          +
          kubectl -n scylla edit Cluster simple-cluster
          +
          +
          +

          Add following task definition to Cluster spec:

          +
            repairs:
          +    - name: "users repair"
          +      keyspace: ["users"]
          +      interval: "1d"
          +  backup:
          +    - name: "weekly backup"
          +      location: ["s3:cluster-backups"]
          +      retention: 3
          +      interval: "7d"
          +    - name: "daily backup"
          +      location: ["s3:cluster-backups"]
          +      retention: 7
          +      interval: "1d"
          +
          +
          +

          For full task definition configuration consult Scylla Cluster CRD.

          +

          Note: Scylla Manager Agent must have access to above bucket prior the update in order to schedule backup task. +Consult Scylla Manager documentation for details on how to set it up.

          +

          Scylla Manager Controller will spot this change and will schedule tasks in Scylla Manager.

          +
          kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
          +
          +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
          +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
          +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
          +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
          +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
          +│ backup/275aae7f-c436-4fc8-bcec-479e65fb8372                 │ -L s3:cluster-backups  --retention 3 │ 23 Sep 20 14:28:58 CEST (+7d)  │ NEW    │
          +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
          +│ repair/d4946360-c29d-4bb4-8b9d-619ada495c2a                 │                                      │ 23 Sep 20 14:38:42 CEST        │ NEW    │
          +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
          +
          +
          +

          As you can see, we have two new tasks, weekly recurring backup, and one repair which should start shortly.

          +

          To check progress of run you can use following command:

          +
          kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task progress --cluster d1d532cd-49f2-4c97-9263-25126532803b repair/d4946360-c29d-4bb4-8b9d-619ada495c2a
          +Status:         RUNNING
          +Start time:     23 Sep 20 14:38:42 UTC
          +Duration:       13s
          +Progress:       2.69%
          +Datacenters:
          +  - us-east-1
          ++--------------------+-------+
          +| system_auth        | 8.06% |
          +| system_distributed | 0.00% |
          +| system_traces      | 0.00% |
          ++--------------------+-------+
          +
          +
          +

          Other tasks can be also tracked using the same command, but using different task ID. +Task IDs are present in Cluster Status as well as in task listing.

          +
          +
          +

          Clean Up

          +

          To clean up all resources associated with Scylla Manager, you can run the commands below.

          +

          NOTE: this will destroy your Scylla Manager database and delete all of its associated data.

          +
          kubectl delete -f examples/common/manager.yaml
          +
          +
          +
          +
          +

          Troubleshooting

          +

          Manager is not running

          +

          If the Scylla Manager does not come up, the first step would be to examine the Manager and Controller logs:

          +
          kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-controller
          +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-scylla-manager-7bd9f968b9-w25jw
          +
          +
          +

          My task wasn’t scheduled

          +

          If your task wasn’t scheduled, Cluster status will be updated with error messages for each failed task. +You can also consult Scylla Manager logs.

          +

          Example:

          +

          Following status describes error when backup task cannot be scheduled, due to lack of access to bucket:

          +
          Status:
          +  Backups:
          +    Error:     create backup target: location is not accessible: 10.100.16.62: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.100.16.62 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.107.193.33: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.107.193.33 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.109.197.60: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.109.197.60 and run "scylla-manager-agent check-location -L s3:manager-test --debug"
          +    Id:        00000000-0000-0000-0000-000000000000
          +    Interval:  0
          +    Location:
          +      s3:manager-test
          +    Name:         adhoc backup
          +    Num Retries:  3
          +    Retention:    3
          +    Start Date:   now
          +  Manager Id:     2b9dbe8c-9daa-4703-a66d-c29f63a917c8
          +  Racks:
          +    us-east-1a:
          +      Members:        3
          +      Ready Members:  3
          +      Version:        4.0.0
          +
          +
          +

          Because Controller is infinitely retrying to schedule each defined task, once permission issues will be resolved, +task should appear in task listing and Cluster status.

          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/migration.html b/v1.10/migration.html new file mode 100644 index 00000000000..2f3e99a4baf --- /dev/null +++ b/v1.10/migration.html @@ -0,0 +1,732 @@ + + + + + + + + + + + + + Version migrations | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Version migrations

          +
          +

          v0.3.0 -> v1.0.0 migration

          +

          v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common kind +which is easier to disambiguate (ScyllaCluster). +This change is backward incompatible, which means manual migration is needed.

          +

          This procedure involves having two CRDs registered at the same time. We will detach Scylla Pods +from Scylla Operator for a short period to ensure that nothing is garbage collected when Scylla Operator is upgraded. +Compared to the upgrade guide where full deletion is requested, this procedure shouldn’t cause downtimes. +Although detaching resources from their controller is considered hacky. This means that you shouldn’t run procedure +out of the box on production. Make sure this procedure works well multiple times on your staging environment first.

          +

          Read the whole procedure and make sure you understand what is going on before executing any of the commands!

          +

          In case of any issues or questions regarding this procedure, you’re welcomed on our Scylla Users Slack +on #kubernetes channel.

          +
          +
          +

          Procedure

          +
            +
          1. Execute this whole procedure for each cluster sequentially. To get a list of existing clusters execute the following

            +
            kubectl -n scylla get cluster.scylla.scylladb.com
            +
            +NAME             AGE
            +simple-cluster   30m
            +
            +
            +

            All below commands will use scylla namespace and simple-cluster as a cluster name.

            +
          2. +
          3. Make sure you’re using v1.0.0 tag:

            +
            git checkout v1.0.0
            +
            +
            +
          4. +
          5. Upgrade your cert-manager to v1.0.0. If you installed it from a static file from this repo, simply execute the following:

            +
             kubectl apply -f examples/common/cert-manager.yaml
            +
            +
            +

            If your cert-manager was installed in another way, follow official instructions on cert-manager website.

            +
          6. +
          7. examples/common/operator.yaml file contains multiple resources. Extract only CustomResourceDefinition to separate file.

          8. +
          9. Install v1.0.0 CRD definition from file created in the previous step:

            +
            kubectl apply -f examples/common/crd.yaml
            +
            +
            +
          10. +
          11. Save your existing simple-cluster Cluster definition to a file:

            +
            kubectl -n scylla get cluster.scylla.scylladb.com simple-cluster -o yaml > existing-cluster.yaml
            +
            +
            +
          12. +
          13. Migrate Kind and ApiVersion to new values using:

            +
            sed -i 's/scylla.scylladb.com\/v1alpha1/scylla.scylladb.com\/v1/g' existing-cluster.yaml
            +sed -i 's/kind: Cluster/kind: ScyllaCluster/g' existing-cluster.yaml
            +
            +
            +
          14. +
          15. Install migrated CRD instance

            +
            kubectl apply -f existing-cluster.yaml
            +
            +
            +

            At this point, we should have two CRDs describing your Scylla cluster, although the new one is not controlled by the Operator.

            +
          16. +
          17. Get UUID of newly created ScyllaCluster resource:

            +
            kubectl -n scylla get ScyllaCluster simple-cluster --template="{{ .metadata.uid }}"
            +
            +12a3678d-8511-4c9c-8a48-fa78d3992694
            +
            +
            +

            Save output UUID somewhere, it will be referred as <new-cluster-uid> in commands below.

            +

            Depending on your shell, you might get additional ‘%’ sign at the end of UUID, make sure to remove it!

            +
          18. +
          19. Upgrade ClusterRole attached to each of the Scylla nodes to grant them permission to lookup Scylla clusters:

            +
            kubectl patch ClusterRole simple-cluster-member --type "json" -p '[{"op":"add","path":"/rules/-","value":{"apiGroups":["scylla.scylladb.com"],"resources":["scyllaclusters"],"verbs":["get"]}}]'
            +
            +
            +

            Amend role name according to your cluster name, it should look like <scylla-cluster-name>-member.

            +
          20. +
          21. Get a list of all Services associated with your cluster. First get list of all services:

            +
             kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
            +
            + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
            + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          109m
            + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
            + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   108m
            + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   106m
            +
            +
            +
          22. +
          23. For each service, change its ownerReference to point to new CRD instance:

            +
             kubectl -n scylla patch svc <cluster-svc-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
            +
            +
            +

            Replace <cluster-svc-name> with Service name, and <new-cluster-uid> with saved UUID from one of the previous steps.

            +
          24. +
          25. Get a list of all Services again to see if none was deleted. Check also “Age” column, it shouldn’t be lower than previous result.

            +
             kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
            +
            + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
            + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          110m
            + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   110m
            + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
            + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   107m
            +
            +
            +
          26. +
          27. Get a list of StatefulSets associated with your cluster:

            +
            kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
            +
            +NAME                                  READY   AGE
            +simple-cluster-us-east-1-us-east-1a   3/3     104m
            +
            +
            +
          28. +
          29. For each StatefulSet from previous step, change its ownerReference to point to new CRD instance.

            +
             kubectl -n scylla patch sts <cluster-sts-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
            +
            +
            +

            Replace <cluster-sts-name> with StatefulSet name, and <new-cluster-uid> with saved UUID from one of the previous steps.

            +
          30. +
          31. Now when all k8s resources bound to Scylla are attached to new CRD, we can remove 0.3.0 Operator and old CRD definition. +Checkout v0.3.0 version, and remove Scylla Operator, and old CRD:

            +
             git checkout v0.3.0
            + kubectl delete -f examples/generic/operator.yaml
            +
            +
            +
          32. +
          33. Checkout v1.0.0, and install upgraded Scylla Operator:

            +
             git checkout v1.0.0
            + kubectl apply -f examples/common/operator.yaml
            +
            +
            +
          34. +
          35. Wait until Scylla Operator boots up:

            +
             kubectl -n scylla-operator-system wait --for=condition=ready pod --all --timeout=600s
            +
            +
            +
          36. +
          37. Get a list of StatefulSets associated with your cluster:

            +
            kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
            +
            +NAME                                  READY   AGE
            +simple-cluster-us-east-1-us-east-1a   3/3     104m
            +
            +
            +
          38. +
          39. For each StatefulSet from previous step, change its sidecar container image to v1.0.0, and wait until change will be propagated. This step will initiate a rolling restart of pods one by one.

            +
            kubectl -n scylla patch sts <cluster-sts> --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/initContainers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
            +kubectl -n scylla rollout status sts <cluster-sts>
            +
            +
            +

            Replace <cluster-sts-name> with StatefulSet name.

            +
          40. +
          41. If you’re using Scylla Manager, bump Scylla Manager Controller image to v1.0.0

            +
             kubectl -n scylla-manager-system patch sts scylla-manager-controller --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
            +
            +
            +
          42. +
          43. Your Scylla cluster is now migrated to v1.0.0.

          44. +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/monitoring.html b/v1.10/monitoring.html new file mode 100644 index 00000000000..3d888bd7e64 --- /dev/null +++ b/v1.10/monitoring.html @@ -0,0 +1,779 @@ + + + + + + + + + + + + + Monitoring | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Monitoring

          +

          Scylla Operator 1.8 introduced a new API resource ScyllaDBMonitoring, allowing users to deploy a managed monitoring +setup for their Scylla Clusters.

          +
          apiVersion: scylla.scylladb.com/v1alpha1
          +kind: ScyllaDBMonitoring
          +metadata:
          +  name: example
          +spec:
          +  type: Platform
          +  endpointsSelector:
          +    matchLabels:
          +      app.kubernetes.io/name: scylla
          +      scylla-operator.scylladb.com/scylla-service-type: identity
          +      scylla/cluster: replace-with-your-scyllacluster-name
          +  components:
          +    prometheus:
          +      storage:
          +        volumeClaimTemplate:
          +          spec:
          +            resources:
          +              requests:
          +                storage: 1Gi
          +    grafana:
          +      exposeOptions:
          +        webInterface:
          +          ingress:
          +            ingressClassName: haproxy
          +            dnsDomains:
          +            - test-grafana.test.svc.cluster.local
          +            annotations:
          +              haproxy-ingress.github.io/ssl-passthrough: "true"
          +
          +
          +

          For details, refer to the below command:

          +
          $ kubectl explain scylladbmonitorings.scylla.scylladb.com/v1alpha1
          +
          +
          +
          +

          Deploy managed monitoring

          +

          Note: as of v1.8, ScyllaDBMonitoring is experimental. The API is currently in version v1alpha1 and may change in future versions.

          +
          +

          Requirements

          +

          Before you can set up your ScyllaDB monitoring, you need Scylla Operator already installed in your Kubernetes cluster. +For more information on how to deploy Scylla Operator, see:

          + +

          The above example of the monitoring setup also makes use of HAProxy Ingress and Prometheus Operator. +You can deploy them in your Kubernetes cluster using the provided third party examples. If you already have them deployed +in your cluster, you can skip the below steps.

          +
          +

          Deploy Prometheus Operator

          +

          Deploy Prometheus Operator using kubectl:

          +
          $ kubectl -n prometheus-operator apply --server-side -f ./examples/third-party/prometheus-operator
          +
          +
          +
          +
          Wait for Prometheus Operator to roll out
          +
          $ kubectl -n prometheus-operator rollout status --timeout=5m deployments.apps/prometheus-operator
          +deployment "prometheus-operator" successfully rolled out
          +
          +
          +
          +
          +
          +

          Deploy HAProxy Ingress

          +

          Deploy HAProxy Ingress using kubectl:

          +
          $ kubectl -n haproxy-ingress apply --server-side -f ./examples/third-party/haproxy-ingress
          +
          +
          +
          +
          Wait for HAProxy Ingress to roll out
          +
          $ kubectl -n haproxy-ingress rollout status --timeout=5m deployments.apps/haproxy-ingress
          +deployment "haproxy-ingress" successfully rolled out
          +
          +
          +
          +
          +
          +
          +

          Deploy ScyllaDBMonitoring

          +

          First, update the endpointsSelector in examples/monitoring/v1alpha1/scylladbmonitoring.yaml with a label +matching your ScyllaCluster instance name.

          +

          Deploy the monitoring setup using kubectl:

          +
          $ kubectl -n scylla apply --server-side -f ./examples/monitoring/v1alpha1/scylladbmonitoring.yaml
          +
          +
          +

          Scylla Operator will notice the new ScyllaDBMonitoring object, and it will reconcile all necessary resources.

          +
          +

          Wait for ScyllaDBMonitoring to roll out

          +
          $ kubectl wait --for='condition=Progressing=False' scylladbmonitorings.scylla.scylladb.com/example
          +scylladbmonitoring.scylla.scylladb.com/example condition met
          +
          +$ kubectl wait --for='condition=Degraded=False' scylladbmonitorings.scylla.scylladb.com/example
          +scylladbmonitoring.scylla.scylladb.com/example condition met
          +
          +$ kubectl wait --for='condition=Available=True' scylladbmonitorings.scylla.scylladb.com/example
          +scylladbmonitoring.scylla.scylladb.com/example condition met
          +
          +
          +
          +
          +

          Wait for Prometheus to roll out

          +
          $ kubectl rollout status --timeout=5m statefulset.apps/prometheus-example
          +statefulset rolling update complete 1 pods at revision prometheus-example-65b89d55bb...
          +
          +
          +
          +
          +

          Wait for Grafana to roll out

          +
          $ kubectl rollout status --timeout=5m deployments.apps/example-grafana
          +deployment "example-grafana" successfully rolled out
          +
          +
          +
          +
          +
          +

          Accessing Grafana

          +

          For accessing Grafana service from outside the Kubernetes cluster we recommend using an Ingress, although there are many other ways to do so. +When using Ingress, what matters is to direct your packets to the ingress controller Service/Pods and have the correct TLS SNI field set by the caller when reaching out to the service, so it is routed properly, and your client can successfully validate the grafana serving certificate. +This is easier when you are using a real DNS domain that resolves to your Ingress controller’s IP address but most clients and tools allow setting the SNI field manually.

          +
          +
          +

          Prerequisites

          +

          To access Grafana, you first need to collect the serving CA and the credentials.

          +
          $ GRAFANA_SERVING_CERT="$( kubectl -n scylla get secret/example-grafana-serving-ca --template '{{ index .data "tls.crt" }}' | base64 -d )"
          +$ GRAFANA_USER="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "username" }}' | base64 -d )"
          +$ GRAFANA_PASSWORD="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "password" }}' | base64 -d )"
          +
          +
          +
          +
          +

          Connecting through Ingress using a resolvable domain

          +

          In production clusters, the Ingress controller and appropriate DNS records should be set up already. Often there is already a generic wildcard record like *.app.mydomain pointing to the Ingress controller’s external IP. For custom service domains, it is usually a CNAME pointing to the Ingress controller’s A record.

          +

          Note: The ScyllaDBMonitoring example creates an Ingress object with test-grafana.test.svc.cluster.local DNS domain that you should adjust to your domain. Below examples use example-grafana.apps.mydomain.

          +

          Note: To test a resolvable domain from your machine without creating DNS records, you can adjust /etc/hosts or similar.

          +
          $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://example-grafana.apps.mydomain" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
          +200
          +
          +
          +
          +
          +

          Connecting through Ingress using an unresolvable domain

          +

          To connect to an Ingress without a resolvable domain you first need to find out your Ingress controller’s IP that can be resolved externally. Again, there are many ways to do so beyond the below examples.

          +

          Unless stated otherwise, we assume your Ingress is running on port 443.

          +
          $ INGRESS_PORT=443
          +
          +
          +
          +

          Variants

          +
          +
          Ingress ExternalIP
          +

          When you are running in a real cluster there is usually a cloud LoadBalancer or a bare metal alternative providing you with an externally reachable IP address.

          +
          $ INGRESS_IP="$( kubectl -n=haproxy-ingress get service/haproxy-ingress --template='{{ ( index .status.loadBalancer.ingress 0 ).ip }}' )"
          +
          +
          +
          +
          +
          Ingress NodePort
          +

          NodePort is slightly less convenient, but it’s available in development clusters as well.

          +
          $ INGRESS_IP="$( kubectl get nodes --template='{{ $internal_ip := "" }}{{ $external_ip := "" }}{{ range ( index .items 0 ).status.addresses }}{{ if eq .type "InternalIP" }}{{ $internal_ip = .address }}{{ else if eq .type "ExternalIP" }}{{ $external_ip = .address }}{{ end }}{{ end }}{{ if $external_ip }}{{ $external_ip }}{{ else }}{{ $internal_ip }}{{ end }}' )"
          +$ INGRESS_PORT="$( kubectl -n=haproxy-ingress get services/haproxy-ingress --template='{{ range .spec.ports }}{{ if eq .port 443 }}{{ .nodePort }}{{ end }}{{ end }}' )"
          +
          +
          +
          +
          +
          Connection
          +
          $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://test-grafana.test.svc.cluster.local:${INGRESS_PORT}" --resolve "test-grafana.test.svc.cluster.local:${INGRESS_PORT}:${INGRESS_IP}" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
          +200
          +
          +
          +
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/nodeoperations/automatic-cleanup.html b/v1.10/nodeoperations/automatic-cleanup.html new file mode 100644 index 00000000000..d2a31ddeb1e --- /dev/null +++ b/v1.10/nodeoperations/automatic-cleanup.html @@ -0,0 +1,571 @@ + + + + + + + + + + + + + Automatic cleanup and replacement in case when k8s node is lost | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Automatic cleanup and replacement in case when k8s node is lost

          +

          In case when your k8s cluster loses one of the nodes due to incident or explicit removal, Scylla Pods may become unschedulable due to PVC node affinity.

          +

          When automaticOrphanedNodeCleanup flag is enabled in your ScyllaCluster, Scylla Operator will perform automatic +node replacement of a Pod which lost his bound resources.

          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/nodeoperations/index.html b/v1.10/nodeoperations/index.html new file mode 100644 index 00000000000..572489e7175 --- /dev/null +++ b/v1.10/nodeoperations/index.html @@ -0,0 +1,571 @@ + + + + + + + + + + + + + Node operations using Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Node operations using Scylla Operator

          +
          +
          +

          Choose a topic:

          + +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/nodeoperations/maintenance-mode.html b/v1.10/nodeoperations/maintenance-mode.html new file mode 100644 index 00000000000..411f044a06f --- /dev/null +++ b/v1.10/nodeoperations/maintenance-mode.html @@ -0,0 +1,580 @@ + + + + + + + + + + + + + Maintenance mode | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Maintenance mode

          +

          When maintenance mode is enabled, readiness probe of Scylla Pod will always return failure and liveness probe will always succeed. This causes that Pod under maintenance +is being removed from K8s Load Balancer and DNS registry but Pod itself stays alive.

          +

          This allows the Scylla Operator to interact with Scylla and Scylla dependencies inside the Pod. +For example user may turn off Scylla process, do something with the filesystem and bring the process back again.

          +

          To enable maintenance mode add scylla/node-maintenance label to service in front of Scylla Pod.

          +
          kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance=""
          +
          +
          +

          To disable, simply remove this label from service.

          +
          kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance-
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/nodeoperations/replace-node.html b/v1.10/nodeoperations/replace-node.html new file mode 100644 index 00000000000..845594f4983 --- /dev/null +++ b/v1.10/nodeoperations/replace-node.html @@ -0,0 +1,654 @@ + + + + + + + + + + + + + Replacing a Scylla node | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Replacing a Scylla node

          +
          +

          Replacing a dead node

          +

          In the case of a host failure, it may not be possible to bring back the node to life.

          +

          Replace dead node operation will cause the other nodes in the cluster to stream data to the node that was replaced. +This operation can take some time (depending on the data size and network bandwidth).

          +

          This procedure is for replacing one dead node. To replace more than one dead node, run the full procedure to completion one node at a time

          +

          Procedure

          +
            +
          1. Verify the status of the node using nodetool status command, the node with status DN is down and need to be replaced

            +
            kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
            +Datacenter: us-east-1
            +=====================
            +Status=Up/Down
            +|/ State=Normal/Leaving/Joining/Moving
            +--  Address        Load       Tokens       Owns    Host ID                               Rack
            +UN  10.43.125.110  74.63 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
            +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
            +DN  10.43.43.51    74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
            +
            +
            +
          2. +
          3. Identify service which is bound to down node by checking IP address

            +
            kubectl -n scylla get svc
            +NAME                                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                           AGE
            +simple-cluster-client                   ClusterIP   None            <none>        9180/TCP                                                          3h12m
            +simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.231.189   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h12m
            +simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.125.110   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h11m
            +simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.43.51     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h5m
            +
            +
            +
          4. +
          5. Drain node which we would like to replace using. This command may delete your data from local disks attached to given node!

            +
            kubectl drain gke-scylla-demo-default-pool-b4b390a1-6j12 --ignore-daemonsets --delete-local-data
            +
            +
            +

            Pod which will be replaced should enter the Pending state

            +
            kubectl -n scylla get pods
            +NAME                                    READY   STATUS    RESTARTS   AGE
            +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h21m
            +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h19m
            +simple-cluster-us-east-1-us-east-1a-2   0/2     Pending   0          8m14s
            +
            +
            +
          6. +
          7. To being node replacing, add scylla/replace="" label to service bound to pod we are replacing.

            +
            kubectl -n scylla label svc simple-cluster-us-east-1-us-east-1a-2 scylla/replace=""
            +
            +
            +

            Your failed Pod should be recreated on available k8s node

            +
            kubectl -n scylla get pods
            +NAME                                    READY   STATUS    RESTARTS   AGE
            +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h27m
            +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h25m
            +simple-cluster-us-east-1-us-east-1a-2   1/2     Running   0          9s
            +
            +
            +

            Because other nodes in cluster must stream data to new node this operation might take some time depending on how much data your cluster stores. +After bootstraping is over, your new Pod should be ready to go. +Old one shouldn’t be no longer visible in nodetool status

            +
            kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
            +Datacenter: us-east-1
            +=====================
            +Status=Up/Down
            +|/ State=Normal/Leaving/Joining/Moving
            +--  Address        Load       Tokens       Owns    Host ID                               Rack
            +UN  10.43.125.110  74.62 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
            +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
            +UN  10.43.191.172  74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
            +
            +
            +
          8. +
          9. Run the repair on the cluster to make sure that the data is synced with the other nodes in the cluster. +You can use Scylla Manager to run the repair.

          10. +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/nodeoperations/restore.html b/v1.10/nodeoperations/restore.html new file mode 100644 index 00000000000..912d94a3290 --- /dev/null +++ b/v1.10/nodeoperations/restore.html @@ -0,0 +1,642 @@ + + + + + + + + + + + + + Restore from backup | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Restore from backup

          +

          This procedure will describe how to restore from backup taken using Scylla Manager to a fresh empty cluster of any size.

          +

          First identify to which snapshot you want to restore. To get list of available snapshot execute following command on Scylla Manager Pod.

          +
          sctool backup list -c <CLUSTER_ID> --all-clusters -L <BACKUP_LOCATION>
          +
          +
          +

          Where:

          +
            +
          • CLUSTER_ID - is a name of a cluster or ID under which ScyllaCluster was registered. You can find it in ScyllaCluster Status.

          • +
          • BACKUP_LOCATION - is a location where backup is stored. For example, for bucket called backups stored in AWS S3, location is s3:backups.

          • +
          +
          sctool backup list -c simple-cluster --all-clusters -L s3:backups
          +Snapshots:
          +  - sm_20201227144037UTC (409MiB)
          +  - sm_20201228145917UTC (434MiB)
          +Keyspaces:
          +  - users (9 tables)
          +  - system_auth (2 tables)
          +  - system_distributed (3 tables)
          +  - system_schema (13 tables)
          +  - system_traces (5 tables)
          +
          +
          +

          To get the list of files use:

          +
          sctool backup files -c <CLUSTER_ID> -L <BACKUP_LOCATION> -T <SNAPSHOT_TAG>
          +
          +
          +

          Where:

          +
            +
          • SNAPSHOT_TAG - name of snapshot you want to restore.

          • +
          +

          Before we start restoring the data, we have to restore the schema. +The first output line is a path to schemas archive, for example:

          +
          s3://backups/backup/schema/cluster/ed63b474-2c05-4f4f-b084-94541dd86e7a/task_287791d9-c257-4850-aef5-7537d6e69d90_tag_sm_20201228145917UTC_schema.tar.gz      ./
          +
          +
          +

          To download this archive you can use AWS CLI tool aws s3 cp.

          +

          This archive contains a single CQL file for each keyspace in the backup.

          +
          tar -ztvf task_287791d9-c257-4850-aef5-7537d6e69d90_tag_sm_20201228145917UTC_schema.tar.gz
          +-rw------- 0/0           12671 2020-12-28 13:17 users.cql
          +-rw------- 0/0            2216 2020-12-28 13:17 system_auth.cql
          +-rw------- 0/0             921 2020-12-28 13:17 system_distributed.cql
          +-rw------- 0/0           12567 2020-12-28 13:17 system_schema.cql
          +-rw------- 0/0            4113 2020-12-28 13:17 system_traces.cql
          +
          +
          +

          Extract this archive and copy each schema file to one of the cluster Pods by:

          +
          kubectl -n scylla cp users.cql simple-cluster-us-east-1-us-east-1a-0:/tmp/users.cql -c scylla
          +
          +
          +

          To import schema simply execute:

          +
          kubectl -n scylla exec simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -f /tmp/users.cql
          +
          +
          +

          Once the schema is recreated we can proceed to downloading data files.

          +

          First let’s save a list of snapshot files to file called backup_files.out:

          +
          kubectl -n scylla-manager exec deployment.apps/scylla-manager-controller -- sctool backup files -c simple-cluster -L s3:backups -T sm_20201228145917UTC > backup_files.out
          +
          +
          +

          We will be using sstableloader to restore data. sstableloader needs a specific directory structure to work namely: <keyspace>/<table>/<contents> +To create this directory structure and download all the files execute these commands:

          +
          mkdir snapshot
          +cd snapshot
          +# Create temporary directory structure.
          +cat ../backup_files.out | awk '{print $2}' | xargs mkdir -p
          +# Download snapshot files.
          +cat ../backup_files.out | xargs -n2 aws s3 cp
          +
          +
          +

          To load data into cluster pass cluster address to sstableloader together with path to data files and credentials:

          +
          sstableloader -d 'simple-cluster-us-east-1-us-east-1a-0.scylla.svc,simple-cluster-us-east-1-us-east-1a-1.scylla.svc,simple-cluster-us-east-1-us-east-1a-2.scylla.svc' ./users/data_0 --username scylla --password <password>
          +
          +
          +

          Depending on how big is your data set, this operation may take some time. +Once it finishes, data from the snapshot is restored and you may clean up the host.

          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/nodeoperations/scylla-upgrade.html b/v1.10/nodeoperations/scylla-upgrade.html new file mode 100644 index 00000000000..9eb8a5d4509 --- /dev/null +++ b/v1.10/nodeoperations/scylla-upgrade.html @@ -0,0 +1,653 @@ + + + + + + + + + + + + + Upgrading version of Scylla | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Upgrading version of Scylla

          +

          To upgrade Scylla version using Operator user have to modify existing ScyllaCluster definition.

          +

          In this example cluster will be upgraded to version 4.4.5.

          +
          kubectl -n scylla patch ScyllaCluster simple-cluster  -p '{"spec":{"version": "4.4.5"}}' --type=merge
          +
          +
          +

          Operator supports two types of version upgrades:

          +
            +
          1. Patch upgrade

          2. +
          3. Generic upgrade

          4. +
          +

          Patch upgrade

          +

          Patch upgrade is executed when only patch version change is detected according to semantic versioning format. +Procedure simply rolls out a restart of whole cluster and upgrades Scylla container image for each node one by one.

          +

          Example: 4.0.0 -> 4.0.1

          +

          Generic upgrade

          +

          Generic upgrades are executed for the non patch version changes.

          +

          Example: 4.0.0 -> 2020.1.0 or 4.0.0 -> 4.1.0 or even 4.0.0 -> nightly

          +

          User can observe current state of upgrade in ScyllaCluster status.

          +
          kubectl -n scylla describe ScyllaCluster simple-cluster
          +[...]
          +Status:
          +  Racks:
          +    us-east-1a:
          +      Members:        3
          +      Ready Members:  3
          +      Version:        4.1.9
          +  Upgrade:
          +    Current Node:         simple-cluster-us-east-1-us-east-1a-2
          +    Current Rack:         us-east-1a
          +    Data Snapshot Tag:    so_data_20201228135002UTC
          +    From Version:         4.1.9
          +    State:                validate_upgrade
          +    System Snapshot Tag:  so_system_20201228135002UTC
          +    To Version:           4.2.2
          +
          +
          +

          Each upgrade begins with taking a snapshot of system and system_schema keyspaces on all nodes in parallel. +Name of this snapshot tag is saved in upgrade status under System Snapshot Tag.

          +

          Before nodes in rack are upgraded, underlying StatefulSet is changed to use OnDelete UpgradeStrategy. +This allows Operator have a full control over when Pod image is changed.

          +

          When a node is being upgraded, maintenance mode is enabled, then the node is drained and snapshot of all data keyspaces is taken. +Snapshot tag is saved under Data Snapshot Tag and is the same for all nodes during the procedure. +Once everything is set up, maintenance mode is disabled and Scylla Pod is deleted. Underlying StatefulSet will bring up a new +Pod with upgraded version. +Once Pod will become ready, data snapshot from this particular node is removed, and Operator moves to next node.

          +

          Once every rack is upgraded, system snapshot is removed from all nodes in parallel and previous StatefulSet UpgradeStrategy is restored. +At this point, all your nodes should be already in desired version.

          +

          Current state of upgrade can be traced using Current Node, Current Rack and State status fields.

          +
            +
          • Current Node shows which node is being upgraded.

          • +
          • Current Rack displays which rack is being upgraded.

          • +
          • State contain information at which stage upgrade is.

          • +
          +

          State can have following values:

          +
            +
          • begin_upgrade - upgrade is starting

          • +
          • check_schema_agreement - Operator waits until all nodes reach schema agreement. It waits for it for 1 minute, prints an error log message and check is retried.

          • +
          • create_system_backup - system keyspaces snapshot is being taken

          • +
          • find_next_rack - Operator finds out which rack must be upgraded next, decision is saved in Current Rack

          • +
          • upgrade_image_in_pod_spec - Image and UpgradeStrategy is upgraded in underlying StatefulSet

          • +
          • find_next_node - Operator finds out which node must be upgraded next, decision is saved in Current Node

          • +
          • enable_maintenance_mode - maintenance mode is being enabled

          • +
          • drain_node - node is being drained

          • +
          • backup_data - snapshot of data keyspaces is being taken

          • +
          • disable_maintenance_mode - maintenance mode is being disabled

          • +
          • delete_pod - Scylla Pod is being deleted

          • +
          • validate_upgrade - Operator validates if new pod enters Ready state and if Scylla version is upgraded

          • +
          • clear_data_backup - snapshot of data keyspaces is being removed

          • +
          • clear_system_backup - snapshot of system keyspaces is being removed

          • +
          • restore_upgrade_strategy - restore UpgradeStrategy in underlying StatefulSet

          • +
          • finish_upgrade - upgrade cleanup

          • +
          +

          Recovering from upgrade failure

          +

          Upgrade may get stuck on validate_upgrade stage. This happens when Scylla Pod refuses to properly boot up.

          +

          To continue with upgrade, first turn off operator by scaling Operator replicas to zero:

          +
          kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=0
          +
          +
          +

          Then user have to manually resolve issue with Scylla by checking what is the root cause of a failure in Scylla container logs. +If needed data and system keyspaces SSTable snapshots are available on the node. You can check ScyllaCluster status for their names.

          +

          Once issue is resolved and Scylla Pod is up and running (Pod is in Ready state), scale Operator back to two replicas:

          +
          kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=2
          +
          +
          +

          Operator should continue upgrade process from where it left off.

          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/objects.inv b/v1.10/objects.inv new file mode 100644 index 00000000000..acd8f3649f3 --- /dev/null +++ b/v1.10/objects.inv @@ -0,0 +1,6 @@ +# Sphinx inventory version 2 +# Project: Scylla Operator +# Version: +# The remainder of this file is compressed using zlib. +xڅTMo +UoUonV4Dųe,>/,c1AhrxQj-?NI8NëIy@Ý6 {[ +mqI OABӉ}!th uhPG5$Z#~%kz\q?#kQ; Cˍl,kE^!9:M'FUgDž%tN0ʼn7hJFv*ʄ={Uט&?hlP7eUA>K4uU/Dtz/̽*E%$rC)Ql`$8`k\`| ExkjG`?Hmݺwu22Qnw8 TlBD +/^%W%hS߆kݗ#&~5Z%̜֊vLV!ݚIU=|WmhUZI\9OO`7׆0Z. lI;$V%'##ȍh&,S9l Sqrn_ \ No newline at end of file diff --git a/v1.10/performance.html b/v1.10/performance.html new file mode 100644 index 00000000000..bd2ec66ed6a --- /dev/null +++ b/v1.10/performance.html @@ -0,0 +1,655 @@ + + + + + + + + + + + + + Performance tuning | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Performance tuning

          +

          Scylla Operator 1.6 introduces a new experimental feature allowing users to optimize Kubernetes nodes.

          +
          +

          Node tuning

          +

          Starting from Operator 1.6, a new CRD called NodeConfig is available, allowing users to target Nodes which should be tuned. +When a Node is supposed to be optimized, the Scylla Operator creates a DaemonSet covering these Nodes. +Nodes matching the provided placement conditions will be subject to tuning.

          +

          Below example NodeConfig tunes nodes having scylla.scylladb.com/node-type=scylla label:

          +
          apiVersion: scylla.scylladb.com/v1alpha1
          +kind: NodeConfig
          +metadata:
          + name: cluster
          +spec:
          + placement:
          +   nodeSelector:
          +     scylla.scylladb.com/node-type: scylla
          +
          +
          +

          For more details about new CRD use:

          +
          kubectl explain nodeconfigs.scylla.scylladb.com/v1alpha1
          +
          +
          +

          For all optimizations we use a Python script available in the Scylla image called perftune. +Perftune executes the performance optmizations like tuning the kernel, network, disk devices, spreading IRQs across CPUs and more.

          +

          Tuning consists of two separate optimizations: common node tuning, and tuning based on Scylla Pods and their resource assignment. +Node tuning is executed immediately. Pod tuning is executed when Scylla Pod lands on the same Node.

          +

          Scylla works most efficently when it’s pinned to CPU and not interrupted. +One of the most common causes of context-switching are network interrupts. Packets coming to a node need to be processed, +and this requires CPU shares.

          +

          On K8s we always have at least a couple of processes running on the node: kubelet, kubernetes provider applications, daemons etc. +These processes require CPU shares, so we cannot dedicate entire node processing power to Scylla, we need to leave space for others.
          We take advantage of it, and we pin IRQs to CPUs not used by any Scylla Pods exclusively.

          +

          Tuning resources are created in a special namespace called scylla-operator-node-tuning.

          +

          The tuning is applied only to pods with Guaranteed QoS class. Please double check your ScyllaCluster resource specification +to see if it meets all conditions.

          +
          +
          +

          Kubernetes tuning

          +

          By default, the kubelet uses the CFS quota to enforce pod CPU limits.
          When the node runs many CPU-bound pods, the workload can move around different CPU cores depending on whether the pod +is throttled and which CPU cores are available. +However, kubelet may be configured to assign CPUs exclusively, by setting the CPU manager policy to static.

          +

          Setting up kubelet configuration is provider specific. Please check the docs for your distribution or talk to your +provider.

          +

          Only pods within the Guaranteed QoS class) can take advantage of this option. +When such pod lands on a Node, kubelet will pin them to specific CPUs, and those won’t be part of the shared pool.

          +

          In our case there are two requirements each ScyllaCluster must fulfill to receive a Guaranteed QoS class:

          +
            +
          • resource request and limits must be equal or only limits have to be provided

          • +
          • agentResources must be provided and their requests and limits must be equal, or only limits have to be provided

          • +
          +

          An example of such a ScyllaCluster that receives a Guaranteed QoS class is below:

          +
          apiVersion: scylla.scylladb.com/v1
          +kind: ScyllaCluster
          +metadata:
          +  name: guaranteed-cluster
          +  namespace: scylla
          +spec:
          +  version: 4.5.1
          +  agentVersion: 2.5.2
          +  datacenter:
          +    name: us-east-1
          +    racks:
          +    - name: us-east-1a
          +      members: 3
          +      storage:
          +        capacity: 500Gi
          +      agentResources:
          +        requests:
          +          cpu: 1
          +          memory: 1G
          +        limits:
          +          cpu: 1
          +          memory: 1G
          +      resources:
          +        requests:
          +          cpu: 4
          +          memory: 16G
          +        limits:
          +          cpu: 4
          +          memory: 16G
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/releases.html b/v1.10/releases.html new file mode 100644 index 00000000000..c8697ee7dc6 --- /dev/null +++ b/v1.10/releases.html @@ -0,0 +1,822 @@ + + + + + + + + + + + + + Releases | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Releases

          +
          +

          Schedule

          +

          We are aiming to ship a new release approximately every 6 weeks. The following release schedule is only advisory, there are no commitments made to hitting these dates.

          + + + + + + + + + + + + + + + +
          ReleaseCode freezeGeneral availability
          1.102022-08-082021-08-15
          +
          +

          Supported releases

          +

          We support the latest 2 releases of the operator to give everyone time to upgrade.

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          ReleaseGeneral availabilitySupport ends
          1.92023-07-04Release of 1.11
          1.82023-01-25Release of 1.10
          1.72022-01-272023-07-04
          1.62021-12-032023-01-25
          1.52021-09-162022-01-27
          1.42021-08-102021-12-03
          1.32021-06-172021-09-16
          1.22021-05-062021-08-10
          1.12021-03-222021-06-17
          1.02021-01-212021-05-06
          +

          Backport policy

          +

          Usually, only important bug fixes are eligible for being backported. +This may depend on the situation and assessment of the maintainers.

          +
          +
          +
          +

          CI/CD

          +

          We use GitHub actions for our CI/CD. Every merge to a supported branch, or a creation of a tag will automatically trigger a job to build, test and publish the container image and other artifacts like helm charts. Before we publish any image, it must pass the e2e suite.

          +
          +

          Automated promotions

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          Git referenceTypeContainer image
          masterbranchdocker.io/scylladb/scylla-operator:latest
          vX.Ybranchdocker.io/scylladb/scylla-operator:X.Y
          vX.Y.Ztagdocker.io/scylladb/scylla-operator:X.Y.Z
          vX.Y.Z-alpha.Ntagdocker.io/scylladb/scylla-operator:X.Y.Z-alpha.N
          vX.Y.Z-beta.Ntagdocker.io/scylladb/scylla-operator:X.Y.Z-beta.N
          vX.Y.Z-rc.Ntagdocker.io/scylladb/scylla-operator:X.Y.Z-rc.N
          +
          +

          Generally available

          +

          GA images aren’t build from scratch but rather promoted from an existing release candidates. When we decide a release candidate has the acceptable quality and QA sings it off, the release candidate is promoted to become the GA release. This makes sure the image has exactly the same content and SHA as the tested release candidate.

          +
          +
          +
          +

          Support matrix

          +

          Support matrix table shows the version requirements for a particular scylla-operator version. Be sure to match these requirements, otherwise some functionality will not work.

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          v1.9v1.8v1.7v1.6v1.5v1.4v1.3v1.2v1.1v1.0
          Kubernetes>=1.21>=1.21>=1.20 && <1.25>=1.19.10 && <1.25>=1.19.10>=1.19.10>=1.19>=1.19>=1.11>=1.11
          CRI APIv1v1alpha2v1alpha2v1alpha2
          Scylla OS>=5.0>=5.0>=4.3>=4.3>=4.3>=4.3>=4.2>=4.2>=4.0>=4.0
          Scylla Enterprise>=2021.1>=2021.1>=2021.1>=2021.1>=2021.1>=2021.1>=2020.1>=2020.1>=2020.1>=2020.1
          Scylla Manager>=2.6>=2.6>=2.2>=2.2>=2.2>=2.2>=2.2>=2.2>=2.2>=2.2
          Scylla Monitoring>=4.0>=4.0>=3.0>=3.0>=1.0>=1.0>=1.0>=1.0>=1.0>=1.0
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/scylla-cluster-crd.html b/v1.10/scylla-cluster-crd.html new file mode 100644 index 00000000000..a8d650afbfd --- /dev/null +++ b/v1.10/scylla-cluster-crd.html @@ -0,0 +1,794 @@ + + + + + + + + + + + + + Scylla Cluster CRD | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Scylla Cluster CRD

          +

          Scylla database clusters can be created and configured using the clusters.scylla.scylladb.com custom resource definition (CRD).

          +

          Please refer to the the user guide walk-through for deployment instructions. +This page will explain all the available configuration options on the Scylla CRD.

          +
          +

          Sample

          +
          apiVersion: scylla.scylladb.com/v1
          +kind: ScyllaCluster
          +metadata:
          +  name: simple-cluster
          +  namespace: scylla
          +spec:
          +  version: 2.3.1
          +  repository: scylladb/scylla
          +  developerMode: true
          +  cpuset: false
          +  automaticOrphanedNodeCleanup: true
          +  repairs:
          +  - name: "weekly us-east-1 repair"
          +    intensity: "2"
          +    interval: "7d"
          +    dc: ["us-east-1"]
          +  backups:
          +  - name: "daily users backup"
          +    rateLimit: ["50"]
          +    location: ["s3:cluster-backups"]
          +    interval: "1d"
          +    keyspace: ["users"]
          +  - name: "weekly full cluster backup"
          +    rateLimit: ["50"]
          +    location: ["s3:cluster-backups"]
          +    interval: "7d"
          +  datacenter:
          +    name: us-east-1
          +    racks:
          +      - name: us-east-1a
          +        members: 3
          +        storage:
          +          capacity: 500G
          +          storageClassName: local-raid-disks
          +        resources:
          +          requests:
          +            cpu: 8
          +            memory: 32Gi
          +          limits:
          +            cpu: 8
          +            memory: 32Gi
          +        placement:
          +          nodeAffinity:
          +            requiredDuringSchedulingIgnoredDuringExecution:
          +              nodeSelectorTerms:
          +                - matchExpressions:
          +                  - key: failure-domain.beta.kubernetes.io/region
          +                    operator: In
          +                    values:
          +                      - us-east-1
          +                  - key: failure-domain.beta.kubernetes.io/zone
          +                    operator: In
          +                    values:
          +                      - us-east-1a
          +          tolerations:
          +            - key: role
          +              operator: Equal
          +              value: scylla-clusters
          +              effect: NoSchedule
          +
          +
          +
          +
          +

          Settings Explanation

          +
          +

          Cluster Settings

          +
            +
          • version: The version of Scylla to use. It is used as the image tag to pull.

          • +
          • agentVersion: The version of Scylla Manager Agent to use. It is used as the image tag to pull.

          • +
          • repository: Optional field. Specifies a custom image repo. If left unset, the official docker hub repo is used (scylladb/scylla).

          • +
          • agentRepository: Optional field. Specifies a custom Scylla Manager Agent image repo. If left unset, the official docker hub repo is used (scylladb/scylla).

          • +
          • developerMode: Optional field. If it’s true, then Scylla is started in developer mode. This setting is for shared test/dev environments.

          • +
          • cpuset: Optional field. If it’s true, then the operator will start Scylla with cpu pinning for maximum performance. For this to work, you need to set the kubelet to use the static cpu policy and only specify limits in resources.

          • +
          • automaticOrphanedNodeCleanup: Optional field. Controls if automatic orphan node cleanup should be performed.

          • +
          • alternator: Optional field. Defines Alternator configuration.

            +
              +
            • port: Port on which to bind to Alternator API.

            • +
            • writeIsolation: required Desired write isolation.

            • +
            +
          • +
          • genericUpgrade: Optional field. Defines GenericUpgrade configuration.

            +
              +
            • failureStrategy: specifies which logic is executed when upgrade failure happens. Currently only Retry is supported.

            • +
            • pollInterval: specifies how often upgrade logic polls on state updates. +Increasing this value should lower number of requests sent to the kube-apiserver, but it may affect +overall time spent during upgrade.

            • +
            +
          • +
          • datacenter: Datacenter definition.

          • +
          • sysctls: Optional field. Sysctl properties to be applied during initialization.

          • +
          • scyllaArgs: Optional field. Command line argument passed to Scylla container image. Note: not all Scylla versions support it.

          • +
          • network: Optional field. Allows to customize network parameters.

            +
              +
            • hostNetworking: controls if host networking should be enabled.

            • +
            • dnsPolicy: controls Scylla Pod DNS Policy. See details.

            • +
            +
          • +
          • repairs: Optional field. Repair tasks definitions. See Scylla Manager settings for details.

          • +
          • backups: Optional field. Repair tasks definitions. See Scylla Manager settings for details.

          • +
          +

          In the Scylla model, each cluster contains datacenters and each datacenter contains racks. At the moment, the operator only supports single datacenter setups.

          +
          +
          +

          Scylla Manager settings

          +

          Tasks are scheduled only when Scylla Manager is deployed in K8s cluster.

          +

          Repairs:

          +
            +
          • name - required - human readable name of the task. It must be unique across all tasks.

          • +
          • startDate - specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, +valid units are d, h, m, s (default “now”).

          • +
          • interval - Optional field. Task schedule interval e.g. 3d2h10m, valid units are d, h, m, s (default “0”).

          • +
          • numRetries - Optional field. The number of times a scheduled task will retry to run before failing (default 3).

          • +
          • dc - Optional field. A list of datacenter glob patterns, e.g. ["dc1", "!otherdc*"] used to specify the DCs to include or exclude from backup.

          • +
          • failFast - Optional field. Stop repair on first error.

          • +
          • intensity - Optional field. Specifies how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. +If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). +Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. +Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. +For Scylla clusters that do not support row-level repair, intensity can be a decimal between (0,1). +In that case it specifies percent of shards that can be repaired in parallel on a repair master node. +For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1. +Intensity is a number passed as string due to lack of support for float values in k8s controller runtime

          • +
          • parallel - Optional field. Specifies the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). +Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. +The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. +The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2.

          • +
          • keyspace - Optional field. A list of keyspace/tables glob patterns, e.g. ["keyspace", "!keyspace.table_prefix_*"] +used to include or exclude keyspaces from repair.

          • +
          • smallTableThreshold - Optional field. Enable small table optimization for tables of size lower than given threshold. +Supported units [B, MiB, GiB, TiB] (default "1GiB").

          • +
          +

          Backups:

          +
            +
          • name - required - human readable name of the task. It must be unique across all tasks.

          • +
          • startDate - Optional field. Specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, +valid units are d, h, m, s (default “now”).

          • +
          • interval - Optional field. task schedule interval e.g. 3d2h10m, valid units are d, h, m, s (default “0”).

          • +
          • numRetries - Optional field. the number of times a scheduled task will retry to run before failing (default 3).

          • +
          • dc - Optional field. A list of datacenter glob patterns, e.g. ["dc1","!otherdc*"] used to specify the DCs to include or exclude from backup.

          • +
          • keyspace - Optional field. A list of keyspace/tables glob patterns, e.g. ["keyspace","!keyspace.table_prefix_*"] used to include or exclude keyspaces from backup.

          • +
          • location - Optional field. A list of backup locations in the format [<dc>:]<provider>:<name> ex. s3:my-bucket. +The <dc>: part is optional and is only needed when different datacenters are being used to upload data to different locations. +<name> Optional field. must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. +The only supported storage at the moment are s3 and gcs.

          • +
          • rateLimit - Optional field. A list of megabytes (MiB) per second rate limits expressed in the format [<dc>:]<limit>. +The <dc>: part is optional and only needed when different datacenters need different upload limits. +Set to 0 for no limit (default 100).

          • +
          • retention - Optional field. The number of backups which are to be stored (default 3).

          • +
          • snapshotParallel - Optional field. A list of snapshot parallelism limits in the format [<dc>:]<limit>. +The <dc>: part is optional and allows for specifying different limits in selected datacenters. +If The <dc>: part is not set, the limit is global (e.g. ["dc1:2,5"]) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters.

          • +
          • uploadParallel - Optional field. A list of upload parallelism limits in the format [<dc>:]<limit>. +The <dc>: part is optional and allows for specifying different limits in selected datacenters. +If The <dc>: part is not set the limit is global (e.g. ["dc1:2,5"]) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters.

          • +
          +
          +
          +

          Datacenter Settings

          +
            +
          • name: Name of the datacenter. Usually, a datacenter corresponds to a region.

          • +
          • racks: List of racks for the specific datacenter.

          • +
          +
          +
          +

          Rack Settings

          +
            +
          • name: Name of the rack. Usually, a rack corresponds to an availability zone.

          • +
          • members: Number of Scylla members for the specific rack. (In Scylla documentation, they are called nodes. We don’t call them nodes to avoid confusion as a Scylla Node corresponds to a Kubernetes Pod, not a Kubernetes Node).

          • +
          • storage: Defines the specs of the underlying storage.

            +
              +
            • capacity: Capacity of the PersistentVolume to request.

            • +
            • storageClassName: Optional field. StorageClass of PersistentVolume to request.

            • +
            +
          • +
          • resources: Defines the CPU and RAM resources for the Scylla Pods.

            +
              +
            • requests: The minimum amount of resources needed to run a Scylla container.

              +
                +
              • cpu: CPU requests.

              • +
              • memory: RAM requests.

              • +
              +
            • +
            • limits: The maximum amount of resources that can be used by a Scylla container.

              +
                +
              • cpu: CPU limits.

              • +
              • memory: RAM limits.

              • +
              +
            • +
            +
          • +
          • agentResources: Optional field. Defines the CPU and RAM resources for the Scylla Manager Agent container. See resources for details.

          • +
          • volumes: Optional field. Defines volumes available in Scylla Pod. See details.

          • +
          • volumeMounts: Optional field. Defines which volumes will be attached to Scylla container.

          • +
          • agentVolumeMounts: Optional field. Defines which volumes will be attached to Agent container.

          • +
          • scyllaConfig: Optional field. name of custom config map which will be merged with Scylla config.

          • +
          • scyllaAgentConfig: Optional field. name of custom secret which will be merged with Scylla Manager Agent config.

          • +
          • placement: Optional field. Defines the placement of Scylla Pods. Has the following subfields:

            + +
          • +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/search.html b/v1.10/search.html new file mode 100644 index 00000000000..2e4e6db237d --- /dev/null +++ b/v1.10/search.html @@ -0,0 +1,546 @@ + + + + + + + + + + + + + Search | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + + + +
          + + + + + +
          + + +
          + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.10/searchindex.js b/v1.10/searchindex.js new file mode 100644 index 00000000000..ed54c4e2f13 --- /dev/null +++ b/v1.10/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["contributing", "eks", "generic", "gke", "helm", "index", "known-issues", "manager", "migration", "monitoring", "nodeoperations/automatic-cleanup", "nodeoperations/index", "nodeoperations/maintenance-mode", "nodeoperations/replace-node", "nodeoperations/restore", "nodeoperations/scylla-upgrade", "performance", "releases", "scylla-cluster-crd", "upgrade"], "filenames": ["contributing.md", "eks.md", "generic.md", "gke.md", "helm.md", "index.rst", "known-issues.md", "manager.md", "migration.md", "monitoring.md", "nodeoperations/automatic-cleanup.md", "nodeoperations/index.rst", "nodeoperations/maintenance-mode.md", "nodeoperations/replace-node.md", "nodeoperations/restore.md", "nodeoperations/scylla-upgrade.md", "performance.md", "releases.md", "scylla-cluster-crd.md", "upgrade.md"], "titles": ["Contributing to Scylla Operator", "Deploying Scylla on EKS", "Deploying Scylla on a Kubernetes Cluster", "Deploying Scylla on GKE", "Deploying Scylla stack using Helm Charts", "Scylla Operator Documentation", "Known issues", "Deploying Scylla Manager on a Kubernetes Cluster", "Version migrations", "Monitoring", "Automatic cleanup and replacement in case when k8s node is lost", "Node operations using Scylla Operator", "Maintenance mode", "Replacing a Scylla node", "Restore from backup", "Upgrading version of Scylla", "Performance tuning", "Releases", "Scylla Cluster CRD", "Upgrade of Scylla Operator"], "terms": {"To": [0, 1, 2, 3, 4, 6, 7, 8, 9, 12, 13, 14, 15, 19], "environ": [0, 2, 4, 8, 18], "must": [0, 2, 7, 13, 15, 16, 17, 18, 19], "have": [0, 1, 2, 3, 4, 7, 8, 9, 14, 15, 16, 19], "follow": [0, 1, 2, 3, 4, 6, 7, 8, 14, 15, 17, 18, 19], "go": [0, 2, 4, 8, 13, 19], "1": [0, 1, 2, 4, 7, 8, 9, 13, 14, 15, 16, 17, 18], "13": [0, 7, 14], "make": [0, 2, 3, 4, 7, 8, 9, 13, 17, 19], "sure": [0, 2, 3, 4, 7, 8, 13, 17, 19], "gopath": 0, "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19], "set": [0, 4, 5, 6, 7, 9, 14, 15, 16], "home": 0, "kustom": 0, "v3": 0, "0": [0, 2, 3, 4, 7, 9, 13, 14, 15, 17, 18], "kubebuild": 0, "v2": 0, "3": [0, 1, 2, 4, 7, 14, 15, 16, 17, 18], "docker": [0, 2, 4, 17, 18, 19], "git": [0, 2, 8, 17, 19], "client": [0, 2, 4, 8, 9, 13], "instal": [0, 2, 5, 7, 8, 9, 19], "github": [0, 2, 5, 9, 17], "account": [0, 3], "all": [0, 1, 2, 3, 4, 7, 8, 9, 14, 15, 16, 18], "depend": [0, 8, 12, 13, 14, 16, 17, 18], "dep": 0, "simpli": [0, 2, 4, 8, 12, 14, 15], "run": [0, 1, 3, 4, 5, 7, 8, 9, 13, 15, 16, 18, 19], "sh": [0, 1, 3], "from": [0, 1, 2, 3, 4, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19], "browser": 0, "navig": 0, "http": [0, 1, 2, 4, 7, 9, 19], "com": [0, 1, 2, 3, 4, 8, 9, 16, 18, 19], "scylladb": [0, 2, 4, 8, 9, 16, 17, 18, 19], "click": 0, "button": 0, "open": [0, 2, 5, 7], "consol": 0, "window": 0, "do": [0, 2, 7, 9, 12, 18, 19], "repo": [0, 4, 8, 18, 19], "path": [0, 2, 8, 14, 19], "mkdir": [0, 14], "p": [0, 3, 8, 14, 15, 19], "src": 0, "local": [0, 9, 13, 18], "cd": [0, 1, 2, 3, 14], "where": [0, 1, 3, 8, 14, 15], "user": [0, 2, 3, 5, 7, 8, 9, 12, 14, 15, 16, 18, 19], "name": [0, 1, 2, 4, 7, 8, 9, 13, 14, 15, 16, 18, 19], "first": [0, 1, 2, 3, 4, 7, 8, 9, 14, 15, 18, 19], "you": [0, 1, 2, 3, 4, 7, 8, 9, 13, 14, 15, 18, 19], "need": [0, 1, 2, 3, 4, 8, 9, 13, 14, 15, 16, 18, 19], "list": [0, 2, 3, 7, 8, 14, 18, 19], "verifi": [0, 2, 13], "wa": [0, 2, 4, 7, 8, 13, 14, 19], "ad": [0, 2, 5], "v": 0, "now": [0, 1, 2, 3, 7, 8, 18], "should": [0, 2, 4, 7, 8, 9, 13, 15, 16, 18], "least": [0, 3, 4, 16], "origin": 0, "can": [0, 1, 2, 3, 4, 7, 8, 9, 13, 14, 15, 16, 18], "also": [0, 1, 2, 3, 4, 5, 7, 8, 9], "other": [0, 3, 4, 7, 9, 13, 16, 17, 18], "collabor": 0, "contributor": 0, "featur": [0, 16], "bug": [0, 17], "fix": [0, 6, 17], "pr": 0, "us": [0, 1, 2, 3, 5, 7, 8, 13, 14, 15, 16, 17, 18, 19], "makefil": 0, "command": [0, 1, 2, 3, 4, 6, 7, 8, 9, 13, 14, 18], "chang": [0, 2, 3, 4, 7, 8, 9, 15, 18, 19], "img": 0, "variabl": 0, "repositori": [0, 2, 18, 19], "access": [0, 7], "push": 0, "wait": [0, 2, 4, 8, 15, 19], "imag": [0, 3, 8, 15, 16, 17, 18, 19], "built": 0, "upload": [0, 18], "new": [0, 2, 3, 5, 7, 8, 9, 13, 15, 16, 17, 19], "base": [0, 4, 16], "start": [0, 1, 2, 7, 14, 15, 16, 18], "work": [0, 1, 3, 4, 8, 14, 16, 17, 18], "ensur": [0, 8], "ar": [0, 1, 2, 3, 4, 7, 8, 9, 13, 15, 16, 17, 18, 19], "up": [0, 4, 5, 8, 9, 13, 14, 15, 16, 19], "date": [0, 4, 7, 17, 18, 19], "latest": [0, 1, 5, 17], "fetch": 0, "off": [0, 2, 12, 15, 17, 19], "master": [0, 17, 18], "give": [0, 2, 3, 7, 17], "simpl": [0, 2, 4, 7, 8, 12, 13, 14, 15, 18, 19], "descript": [0, 4], "gener": [0, 1, 2, 3, 7, 8, 9, 15, 19], "two": [0, 4, 7, 8, 15, 16, 19], "three": [0, 4, 7], "word": 0, "separ": [0, 1, 3, 8, 16], "dash": [0, 18], "without": [0, 3, 4, 9], "number": [0, 2, 18, 19], "checkout": [0, 8, 19], "b": [0, 3, 12, 18], "readi": [0, 2, 4, 7, 8, 12, 13, 15, 19], "dure": [0, 15, 18, 19], "lifecycl": 0, "keep": [0, 1, 3], "As": [0, 1, 3, 7], "team": 0, "rebas": 0, "top": 0, "thi": [0, 1, 2, 3, 4, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19], "avoid": [0, 18], "unnecessari": 0, "merg": [0, 15, 17, 18], "clean": [0, 14], "whenev": 0, "never": [0, 19], "want": [0, 1, 2, 3, 4, 7, 14, 19], "alwai": [0, 2, 12, 16], "otherwis": [0, 9, 17], "end": [0, 8, 9, 17], "If": [0, 1, 2, 3, 4, 6, 7, 8, 9, 15, 18], "ani": [0, 3, 4, 8, 14, 16, 17, 18], "modifi": [0, 3, 15], "file": [0, 2, 3, 4, 8, 14, 19], "stash": 0, "them": [0, 1, 2, 3, 4, 8, 9, 16, 18, 19], "save": [0, 2, 8, 14, 15, 19], "u": [0, 1, 2, 3, 4, 7, 8, 12, 13, 14, 15, 16, 18], "some": [0, 2, 4, 7, 13, 14, 17], "veri": [0, 4, 8, 19], "power": [0, 16], "understand": [0, 8], "how": [0, 1, 3, 4, 7, 9, 13, 14, 18], "els": [0, 9], "risk": 0, "lose": [0, 10], "read": [0, 1, 3, 4, 8], "about": [0, 1, 2, 3, 4, 16], "document": [0, 1, 2, 3, 4, 7, 18], "well": [0, 1, 2, 3, 7, 8, 9], "worth": 0, "In": [0, 2, 3, 4, 7, 8, 9, 10, 13, 15, 16, 18, 19], "nutshel": 0, "doe": [0, 2, 4, 7], "unwind": 0, "remov": [0, 2, 4, 8, 10, 12, 15, 19], "temporarili": 0, "The": [0, 1, 2, 3, 5, 6, 7, 9, 14, 16, 17, 18], "re": [0, 8, 19], "appli": [0, 1, 2, 3, 4, 6, 7, 8, 9, 16, 18, 19], "one": [0, 2, 4, 7, 8, 10, 13, 14, 15, 18, 19], "conflict": 0, "prompt": 0, "befor": [0, 8, 9, 14, 15, 17, 18, 19], "continu": [0, 15], "output": [0, 2, 7, 8, 14], "close": [0, 4], "It": [0, 1, 2, 3, 4, 15, 18], "tell": 0, "complet": [0, 2, 9, 13], "when": [0, 1, 2, 3, 7, 8, 9, 11, 12, 15, 16, 17, 18], "done": [0, 1, 2, 3, 7], "see": [0, 1, 2, 3, 4, 5, 7, 8, 9, 16, 18], "onc": [0, 1, 2, 3, 4, 7, 14, 15, 19], "implement": 0, "unit": [0, 18], "test": [0, 7, 9, 17, 18], "pass": [0, 3, 14, 17, 18], "integr": [0, 5], "order": [0, 2, 3, 7, 19], "requir": [0, 1, 2, 3, 6, 16, 17, 18, 19], "again": [0, 8, 9, 12], "prepar": 0, "minim": [0, 4], "logic": [0, 18], "so": [0, 2, 3, 4, 9, 16, 19], "we": [0, 1, 2, 3, 4, 7, 8, 9, 13, 14, 16, 17, 18, 19], "maintain": [0, 17], "most": [0, 1, 2, 3, 4, 9, 16, 18], "commonli": 0, "includ": [0, 4, 18], "singl": [0, 4, 7, 14, 18], "squash": 0, "although": [0, 4, 8, 9], "sometim": [0, 2], "multipl": [0, 2, 7, 8], "inspect": 0, "determin": 0, "log": [0, 2, 7, 15, 18], "edit": [0, 1, 2, 3, 7], "even": [0, 15], "reorder": 0, "exampl": [0, 1, 2, 3, 4, 7, 8, 9, 12, 14, 15, 16, 19], "last": 0, "5": [0, 7, 14, 15, 16, 17, 18], "tool": [0, 1, 9, 14], "head": 0, "pleas": [0, 4, 16, 18, 19], "line": [0, 14, 18], "summari": 0, "would": [0, 2, 7, 13], "like": [0, 2, 5, 7, 8, 9, 13, 16, 17], "prefix": 0, "relev": 0, "directori": [0, 14, 19], "colon": 0, "changelog": 0, "get": [0, 1, 2, 3, 4, 7, 8, 9, 13, 14, 15, 19], "made": [0, 17], "look": [0, 2, 4, 8], "just": [0, 1, 2, 3], "good": [0, 4], "more": [0, 1, 2, 3, 4, 9, 13, 16, 18], "sai": 0, "enter": [0, 4, 13, 15], "blank": 0, "carri": 0, "rememb": [0, 2], "why": 0, "itself": [0, 4, 7, 12], "show": [0, 2, 15, 17], "what": [0, 2, 4, 7, 8, 9, 15], "write": [0, 2, 18], "better": [0, 3], "than": [0, 2, 8, 13, 18], "less": [0, 8, 9, 19], "compar": [0, 8], "behaviour": 0, "after": [0, 1, 2, 3, 4, 7, 13], "imagin": 0, "yourself": 0, "12": [0, 7, 14, 17], "month": 0, "time": [0, 4, 7, 8, 13, 14, 17, 18], "ve": 0, "forgotten": 0, "everyth": [0, 1, 2, 3, 4, 15], "did": 0, "speed": 0, "quickli": 0, "an": [0, 2, 4, 5, 15, 16, 17, 18, 19], "issu": [0, 5, 7, 8, 15, 19], "1234": 0, "subject": [0, 16], "fit": 0, "don": [0, 1, 3, 4, 18], "t": [0, 1, 2, 3, 4, 7, 8, 13, 14, 16, 17, 18, 19], "associ": [0, 2, 7, 8], "put": 0, "link": [0, 6], "here": [0, 2, 19], "short": [0, 8], "sidecar": [0, 2, 4, 8, 19], "reconcil": [0, 9], "loop": 0, "And": [0, 4], "longer": [0, 2, 3, 13], "api": [0, 2, 7, 9, 17, 18], "support": [0, 2, 4, 5, 7, 15, 18, 19], "host": [0, 7, 9, 13, 14, 18], "network": [0, 13, 16, 18], "crd": [0, 2, 4, 5, 7, 8, 16, 19], "ha": [0, 2, 3, 17, 18], "properti": [0, 2, 18], "select": [0, 18], "apropri": 0, "dn": [0, 2, 9, 12, 13, 18], "polici": [0, 1, 3, 4, 16, 18], "recent": 0, "obviou": 0, "tab": 0, "track": [0, 2, 7], "automat": [0, 2, 3, 7, 11, 17, 18, 19], "guid": [1, 2, 3, 4, 7, 8, 18, 19], "focus": [1, 3], "improv": 1, "perform": [1, 2, 3, 5, 10, 18], "trick": 1, "won": [1, 16], "differ": [1, 2, 4, 7, 16, 18], "machin": [1, 2, 3, 9], "tier": 1, "kubelet": [1, 3, 16, 18], "static": [1, 3, 8, 16, 18], "cpu": [1, 2, 3, 4, 16, 18], "sdd": [1, 3], "disk": [1, 2, 3, 13, 16, 18], "raid0": [1, 3], "maximum": [1, 3, 18], "same": [1, 2, 3, 4, 7, 8, 15, 16, 17, 18], "tri": [1, 3], "step": [1, 2, 3, 4, 7, 8, 9, 19], "accord": [1, 2, 3, 8, 15], "your": [1, 2, 3, 4, 6, 7, 8, 9, 10, 13, 14, 15, 16, 19], "prefer": [1, 3], "eks_region": 1, "east": [1, 2, 4, 7, 8, 13, 14, 15, 16, 18], "eks_zon": 1, "1a": [1, 2, 7, 8, 13, 14, 15, 16, 18], "1b": [1, 4], "1c": 1, "insid": [1, 2, 3, 12], "folder": [1, 3], "z": [1, 3, 17], "r": 1, "benchmark": [1, 3], "cassandra": [1, 3], "stress": [1, 3], "export": [1, 3], "option": [1, 2, 3, 4, 7, 16, 18], "own": [1, 3, 4, 13], "cluster_nam": [1, 2, 3], "demo": [1, 3, 13], "For": [1, 2, 4, 5, 7, 8, 9, 12, 14, 16, 18], "ll": [1, 3], "A": [1, 2, 3, 4, 9, 18, 19], "nodegroup": 1, "i3": 1, "2xlarg": 1, "pod": [1, 2, 3, 4, 7, 8, 9, 10, 12, 13, 14, 15, 16, 18], "These": [1, 3, 16, 19], "onli": [1, 2, 8, 15, 16, 17, 18, 19], "accept": [1, 17], "toler": [1, 18], "pool": [1, 3, 13, 16], "instancetyp": 1, "desiredcapac": 1, "label": [1, 2, 3, 9, 12, 13, 16], "type": [1, 3, 4, 8, 9, 13, 15, 16, 17], "taint": [1, 3], "role": [1, 2, 3, 8, 18], "noschedul": [1, 3, 18], "ssh": [1, 6, 7], "allow": [1, 2, 4, 9, 12, 15, 16, 18], "true": [1, 2, 4, 7, 9, 18, 19], "kubeletextraconfig": 1, "cpumanagerpolici": [1, 3], "4": [1, 2, 3, 4, 7, 15, 16, 17], "c4": 1, "later": [1, 3], "larg": 1, "monitor": [1, 3, 5, 17], "stack": [1, 3, 5, 9], "sever": 1, "eksctl": 1, "doc": [1, 2, 16], "aw": [1, 14], "amazon": 1, "userguid": 1, "html": 1, "kubectl": [1, 2, 3, 4, 7, 8, 9, 12, 13, 14, 15, 16], "kubernet": [1, 4, 5, 8, 9, 17, 18], "io": [1, 2, 9, 17, 18, 19], "task": [1, 2, 5, 18], "except": [1, 3], "develop": [1, 3, 7, 9, 18], "mode": [1, 3, 7, 11, 15, 18], "storag": [1, 2, 3, 4, 9, 16, 18, 19], "xf": [1, 3], "filesystem": [1, 3, 12], "nvme": [1, 3], "cloud": [1, 2, 3, 7, 9], "provid": [1, 2, 3, 4, 9, 16, 18], "usual": [1, 3, 9, 17, 18], "come": [1, 2, 3, 7, 16], "individu": [1, 3], "devic": [1, 3, 16], "full": [1, 2, 3, 7, 8, 13, 15, 18], "capac": [1, 3, 4, 16, 18], "togeth": [1, 3, 14], "form": [1, 3], "raid": [1, 3, 18], "arrai": [1, 3], "those": [1, 2, 3, 16], "nodeconfig": [1, 3, 16], "necessari": [1, 2, 3, 9], "creation": [1, 3, 7, 17], "optim": [1, 3, 16, 18], "tune": [1, 3, 5], "section": [1, 3], "": [1, 2, 3, 4, 7, 8, 9, 13, 14, 16, 18, 19], "let": [1, 3, 4, 7, 14], "take": [1, 2, 3, 13, 14, 15, 16, 18], "care": [1, 3], "abov": [1, 2, 3, 4, 7, 9, 19], "server": [1, 2, 3, 7, 9, 19], "side": [1, 3, 9, 19], "f": [1, 2, 3, 4, 7, 8, 9, 14, 19], "gke": [1, 2, 5, 13], "alpha": [1, 3, 17], "yaml": [1, 2, 3, 4, 7, 8, 9, 19], "afterward": [1, 3], "capabl": [1, 2, 3], "dynam": [1, 3], "provis": [1, 2, 3, 4], "persistentvolum": [1, 2, 3, 18], "mount": [1, 2, 3], "earlier": [1, 3], "over": [1, 3, 13, 15], "n": [1, 2, 3, 4, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19], "csi": [1, 3], "driver": [1, 2, 3], "common": [1, 2, 3, 4, 7, 8, 16, 19], "storageclass_xf": [1, 3], "launch": [1, 3], "highli": [1, 3], "instruct": [1, 2, 3, 4, 8, 18], "found": [1, 2, 3], "experi": [1, 3], "mean": [2, 8], "ideal": 2, "best": 2, "fast": 2, "direct": [2, 9], "extra": 2, "setup": [2, 9, 18], "which": [2, 3, 4, 5, 7, 8, 10, 13, 14, 15, 16, 18, 19], "platform": [2, 9], "specif": [2, 4, 14, 16, 18, 19], "check": [2, 5, 7, 8, 13, 15, 16, 19], "detail": [2, 7, 9, 16, 18], "particular": [2, 4, 15, 17], "class": [2, 16], "helm": [2, 5, 9, 17], "enabl": [2, 3, 6, 7, 10, 12, 15, 18], "stabl": [2, 4, 19], "daunt": 2, "error": [2, 3, 7, 15, 18], "prone": 2, "fortun": 2, "wai": [2, 3, 7, 8, 9], "life": [2, 13], "easier": [2, 8, 9, 19], "minikub": [2, 4], "breez": 2, "littl": 2, "bit": [2, 4], "resourc": [2, 5, 7, 8, 9, 10, 16, 18, 19], "default": [2, 3, 4, 6, 7, 13, 16, 18], "6": [2, 16, 17, 18], "Then": [2, 3, 4, 15], "awar": 2, "eval": 2, "env": 2, "manifest": [2, 19], "clone": 2, "either": [2, 4, 7], "upsteam": [2, 4], "self": [2, 4], "sign": [2, 4, 8], "certif": [2, 4, 9], "until": [2, 4, 8, 15, 19], "condit": [2, 4, 8, 9, 16, 19], "establish": [2, 19], "issuer": 2, "rollout": [2, 8, 9, 19], "statu": [2, 4, 5, 7, 8, 9, 13, 14, 15, 19], "deploy": [2, 4, 7, 9, 14, 15, 18, 19], "app": [2, 4, 9, 14, 15, 19], "webhook": [2, 19], "namespac": [2, 4, 7, 8, 16, 18, 19], "scyllaclust": [2, 4, 8, 9, 10, 14, 15, 16, 18, 19], "instanc": [2, 3, 4, 7, 8, 9], "valu": [2, 3, 4, 8, 15, 18], "feel": 2, "free": [2, 3], "brows": 2, "tweak": 2, "object": [2, 9, 19], "been": 2, "repres": 2, "our": [2, 8, 16, 17, 19], "below": [2, 7, 8, 9, 16, 18], "import": [2, 3, 14, 17], "becaus": [2, 7, 13], "successfulli": [2, 9], "extend": 2, "citizen": 2, "nativ": 2, "easi": 2, "someth": [2, 7, 12], "restart": [2, 4, 7, 8, 13, 15, 19], "ag": [2, 4, 7, 8, 13, 19], "2": [2, 3, 4, 7, 8, 12, 13, 14, 15, 16, 17, 18], "9m49": 2, "7m43": 2, "6m46": 2, "note": [2, 7, 9, 18, 19], "pattern": [2, 4, 18], "datacenter_nam": 2, "rack_nam": 2, "instance_numb": 2, "specifi": [2, 4, 18], "_": [2, 6, 18], "datacent": [2, 4, 7, 13, 16], "rack": [2, 4, 5, 7, 13, 15, 16], "attach": [2, 3, 8, 13, 18], "pick": 2, "resembl": 2, "find": [2, 4, 9, 14, 15, 19], "servic": [2, 4, 8, 9, 12, 13], "inconsequenti": 2, "thei": [2, 7, 18], "anyth": 2, "desir": [2, 4, 7, 15, 18], "member": [2, 4, 7, 8, 15, 16, 18], "entri": 2, "l": [2, 4, 7, 8, 9, 14], "state": [2, 4, 7, 9, 13, 15, 18], "its": [2, 7, 8], "current": [2, 4, 5, 9, 15, 18], "describ": [2, 7, 8, 14, 15, 19], "squeez": 2, "out": [2, 5, 8, 14, 15, 19], "emploi": 2, "version": [2, 3, 4, 5, 7, 9, 11, 16, 17, 18, 19], "agentvers": [2, 16, 18], "cpuset": [2, 18], "hostnetwork": [2, 18], "result": [2, 8, 18], "defin": [2, 4, 7, 18], "sysctl": [2, 18], "kei": [2, 7, 18], "pair": 2, "increas": [2, 18], "event": 2, "avail": [2, 3, 4, 7, 9, 13, 14, 15, 16, 18, 19], "asynchron": 2, "process": [2, 3, 12, 15, 16, 19], "linux": 2, "aio": 2, "max": [2, 18], "nr": 2, "spec": [2, 4, 7, 8, 9, 15, 16, 18, 19], "2097152": 2, "instead": 2, "regular": [2, 7], "small": [2, 7, 18], "definit": [2, 3, 4, 5, 7, 8, 15, 18, 19], "developermod": [2, 18], "port": [2, 4, 8, 9, 13, 18, 19], "8000": 2, "writeisol": [2, 18], "only_rmw_uses_lwt": 2, "whichev": 2, "isol": [2, 18], "forbid": 2, "rmw": 2, "lwt": 2, "between": [2, 18], "level": [2, 7, 18], "cql": [2, 7, 14], "pure": 2, "alien": 2, "cqlsh": [2, 14], "shell": [2, 8], "exec": [2, 7, 13, 14], "keyspac": [2, 7, 14, 15, 18], "convent": 2, "connect": [2, 7], "python": [2, 16], "svc": [2, 7, 8, 9, 12, 13, 14], "session": 2, "plain": 2, "configmap": 2, "refer": [2, 4, 8, 9, 17, 18, 19], "call": [2, 3, 14, 16, 18, 19], "rest": [2, 7], "config": [2, 3, 7, 18], "propag": [2, 8], "statefulset": [2, 4, 8, 9, 15, 19], "rackdc": 2, "tmp": [2, 14], "o": [2, 8, 9, 17], "dry": 2, "replac": [2, 5, 8, 9, 11, 19], "overrid": 2, "prefer_loc": 2, "dc_suffix": 2, "second": [2, 18], "each": [2, 3, 4, 7, 8, 14, 15, 16, 18, 19], "serv": [2, 4, 9], "main": [2, 4, 7], "endpoint": 2, "interact": [2, 12], "variou": 2, "thing": 2, "secur": 2, "backup": [2, 5, 7, 11, 18, 19], "secret": [2, 4, 9, 18], "popul": 2, "content": [2, 3, 4, 14, 17], "copi": [2, 14], "auto": 2, "empti": [2, 14], "being": [2, 7, 12, 13, 15, 17, 18], "decod": 2, "roll": [2, 4, 5, 8, 15, 19], "prometheu": [2, 4, 5, 7], "grafana": [2, 5], "addit": [2, 4, 7, 8, 19], "field": [2, 4, 9, 15, 18], "add": [2, 4, 7, 8, 12, 13, 19], "append": 2, "choos": [2, 5, 11], "inform": [2, 9, 15], "happen": [2, 15, 18], "along": 2, "mini": 2, "cli": [2, 4, 7, 14], "job": [2, 17, 18], "against": 2, "doesn": [2, 3, 19], "core": [2, 3, 16], "count": [2, 3, 7], "10": [2, 4, 7, 8, 13, 17], "50": [2, 18], "000": 2, "throttl": [2, 16], "throughput": 2, "30": 2, "op": [2, 8], "sec": 2, "total": 2, "300": 2, "hack": 2, "cass": 2, "gen": 2, "py": 2, "num": [2, 3, 7], "memori": [2, 4, 16, 18], "20g": 2, "50000000": 2, "limit": [2, 4, 7, 16, 18], "30000": 2, "script": [2, 3, 16], "proper": 2, "argument": [2, 7, 18], "case": [2, 8, 13, 16, 18, 19], "alter": 2, "h": [2, 18], "usag": 2, "num_job": 2, "scylla_vers": 2, "thread": 2, "per": [2, 18], "connections_per_host": 2, "print": [2, 14, 15], "stdout": 2, "nodeselector": [2, 16], "templat": [2, 8, 9, 19], "help": [2, 5], "messag": [2, 7, 15], "exit": 2, "ip": [2, 4, 6, 8, 9, 13], "gb": 2, "ie": 2, "2g": 2, "10000000": 2, "rate": [2, 18], "certain": 2, "node": [2, 4, 5, 7, 8, 9, 12, 15, 18], "selector": [2, 19], "eg": 2, "while": 2, "metric": [2, 4], "finish": [2, 14], "delet": [2, 7, 8, 13, 15, 19], "walk": [2, 18], "through": [2, 4, 18], "destroi": [2, 7], "data": [2, 3, 7, 9, 13, 14, 15, 18, 19], "examin": [2, 7], "ok": 2, "persist": [3, 7], "guarante": [3, 16], "gcp_user": 3, "gcloud": 3, "format": [3, 7, 15, 18], "gcp_project": 3, "project": [3, 5], "gcp_zone": 3, "west1": 3, "yanniszark": 3, "arrikto": 3, "226716": 3, "warn": 3, "zone": [3, 5, 18], "ex": [3, 18], "region": [3, 18], "gcp_region": 3, "cluster_vers": 3, "contain": [3, 4, 8, 14, 15, 17, 18, 19], "validmastervers": 3, "manag": [3, 5, 8, 13, 14, 16, 17, 19], "systemconfig": 3, "kubeletconfig": 3, "nodepool": 3, "n1": 3, "standard": 3, "8": [3, 7, 9, 17, 18], "purpos": 3, "pd": 3, "ssd": 3, "size": [3, 13, 14, 18], "20": [3, 7, 17], "ubuntu_containerd": 3, "system": [3, 8, 15, 19], "stackdriv": 3, "autoupgrad": 3, "autorepair": 3, "32": 3, "raw": 3, "block": 3, "disabl": [3, 4, 6, 12, 15], "upgrad": [3, 4, 5, 8, 11, 17, 18], "repair": [3, 5, 7, 13, 18], "hard": 3, "timeout": [3, 4, 7, 8, 9], "respect": 3, "pdb": 3, "forc": 3, "comput": 3, "At": [3, 8, 15, 18], "point": [3, 8, 9, 15], "handl": 3, "manual": [3, 8, 9, 15, 19], "control": [3, 7, 8, 9, 14, 15, 18, 19], "By": [3, 4, 16, 18], "rbac": 3, "permiss": [3, 7, 8], "credenti": [3, 7, 9, 14], "clusterrolebind": 3, "easiest": 3, "obtain": 3, "gcp": 3, "iam": 3, "web": 3, "interfac": 3, "bind": [3, 18], "clusterrol": [3, 8], "sed": [3, 8, 19], "g": [3, 8, 18, 19], "inject": 3, "match": [3, 9, 16, 17], "compon": [4, 7, 9], "k8": [4, 5, 7, 8, 11, 12, 13, 16, 18], "cluster": [4, 5, 8, 9, 10, 12, 13, 14, 15, 16, 19], "could": 4, "16": [4, 7, 17], "googleapi": [4, 19], "updat": [4, 7, 9, 18, 19], "creat": [4, 7, 8, 9, 14, 16, 18, 19], "autogener": 4, "60": [4, 7], "execut": [4, 6, 7, 8, 14, 15, 16, 18], "search": 4, "v1": [4, 7, 9, 16, 17, 18], "hardwar": 4, "rewrit": 4, "ca": [4, 9], "autom": [4, 5, 7, 19], "databas": [4, 7, 18], "ma": 4, "reason": 4, "interest": 4, "customiz": 4, "sourc": [4, 5, 7, 19], "download": [4, 14], "hub": [4, 18], "pullpolici": 4, "fullfil": 4, "pull": [4, 18, 19], "url": 4, "compos": 4, "follw": 4, "tag": [4, 8, 15, 17, 18, 19], "ifnotpres": 4, "much": [4, 13], "alloc": 4, "via": 4, "100m": 4, "128mi": 4, "request": [4, 8, 9, 16, 18], "32mi": 4, "decid": [4, 17], "whether": [4, 16], "createselfsignedcertif": 4, "certificatesecretnam": 4, "overwrit": 4, "under": [4, 7, 12, 14, 15], "cours": 4, "scyllaimag": 4, "agentimag": 4, "agent": [4, 7, 18], "express": [4, 18], "5g": 4, "1gi": [4, 9], "gib": [4, 18], "customzi": 4, "consist": [4, 7, 16], "applic": [4, 16], "mani": [4, 9, 16, 18], "500m": 4, "500mi": 4, "similarli": 4, "controllerimag": 4, "controllerresourc": 4, "30mi": 4, "20mi": 4, "intern": [4, 7], "dedic": [4, 7, 16], "land": [4, 16], "bootstrap": [4, 13], "isn": 4, "valid": [4, 7, 9, 15, 18, 19], "correctli": 4, "5dbcb54f5c": 4, "vjm4m": 4, "51": [4, 13], "wfjbw": 4, "extern": [4, 8, 9, 13], "clusterip": [4, 8, 13], "105": 4, "207": 4, "130": 4, "none": [4, 8, 13], "443": [4, 9], "tcp": [4, 8, 13], "TO": 4, "replicaset": 4, "669db64dd": 4, "bcm4v": 4, "89": 4, "844ccc56c4": 4, "drbth": 4, "rhwqx": 4, "231": [4, 13], "53": [4, 7], "80": 4, "5090": 4, "9180": [4, 8, 13], "5m58": 4, "4m29": 4, "5m59": 4, "43": [4, 8, 13], "149": 4, "92": 4, "7000": [4, 8, 13], "7001": [4, 8, 13], "7199": [4, 8, 13], "10001": [4, 8, 13], "9042": [4, 8, 13], "9142": [4, 8, 13], "9160": [4, 8, 13], "49": 4, "exactli": [4, 17], "were": 4, "ask": 4, "spin": [4, 7], "servicemonitor": 4, "observ": [4, 15], "managg": 4, "both": 4, "fals": [4, 7, 9, 18], "notic": [4, 9], "prometh": 4, "abl": 4, "scrape": 4, "uninstal": 4, "enterpris": [5, 7, 17], "deploi": [5, 18, 19], "relat": 5, "downscal": 5, "report": 5, "lesson": 5, "univers": 5, "multi": 5, "scale": [5, 15], "down": [5, 13], "dead": 5, "autoh": 5, "topic": [5, 11], "begin": [5, 15], "ek": 5, "chart": [5, 9, 17, 19], "experiment": [5, 9, 16, 19], "procedur": [5, 13, 14, 15, 19], "releas": [5, 19], "known": 5, "custom": [5, 7, 9, 18], "contribut": 5, "fail": [6, 7, 9, 13, 18], "8th": 6, "migrat": [6, 19], "008": 6, "hairpin": 6, "On": [6, 16], "sudo": 6, "docker0": 6, "promisc": 6, "product": [7, 8, 9], "oper": [7, 8, 10, 12, 13, 14, 15, 16, 17, 18], "wide": 7, "predict": 7, "With": 7, "proprietari": 7, "softwar": 7, "licens": 7, "agreement": [7, 15], "spawn": 7, "mission": 7, "watch": 7, "synchron": 7, "regist": [7, 8, 14], "id": [7, 13, 14], "map": [7, 18], "reach": [7, 9, 15], "fulli": 7, "unschedul": [7, 10], "bare": [7, 9], "metal": [7, 9], "dc": [7, 18], "37m": 7, "28m": 7, "7bd9f968b9": 7, "w25jw": 7, "info": 7, "2020": [7, 14, 15, 17], "09": [7, 17], "23t11": 7, "25": [7, 8, 17], "27": [7, 17], "882z": 7, "m": [7, 18], "build_dat": 7, "commit": [7, 17], "built_bi": 7, "go_vers": 7, "loglevel": 7, "debug": 7, "apiaddress": 7, "127": 7, "5080": 7, "_trace_id": 7, "lqejv3kdr5gx9m3xq2ynnq": 7, "28": [7, 14], "435z": 7, "26": 7, "238z": 7, "20200816": 7, "76cc4dcc": 7, "pid": 7, "xqhkj0our8e6imdepm62hg": 7, "54": 7, "519z": 7, "tlscertfil": 7, "var": 7, "lib": 7, "scylla_manag": 7, "crt": [7, 9], "tlskeyfil": 7, "tlscafil": 7, "56090": 7, "prometheusscrapeinterv": 7, "5000000000": 7, "56112": 7, "logger": 7, "stderr": 7, "ssl": [7, 9], "password": [7, 9, 14], "localdc": 7, "migratedir": 7, "etc": [7, 9, 16], "migratetimeout": 7, "30000000000": 7, "migratemaxwaitschemaagr": 7, "300000000000": 7, "replicationfactor": 7, "600000000": 7, "tokenawar": 7, "certfil": 7, "usercertfil": 7, "userkeyfil": 7, "healthcheck": 7, "250000000": 7, "ssltimeout": 7, "750000000": 7, "diskspacefreeminperc": 7, "agemax": 7, "43200000000000": 7, "segmentsperrepair": 7, "shardparallelmax": 7, "shardfailedsegmentsmax": 7, "100": [7, 18], "pollinterv": [7, 18], "200000000": 7, "errorbackoff": 7, "shardingignoremsbbit": 7, "config_fil": 7, "mnt": 7, "tutori": 7, "alreadi": [7, 9, 15], "d1d532cd": 7, "49f2": 7, "4c97": 7, "9263": 7, "25126532803b": 7, "talk": [7, 16], "sctool": [7, 14], "ti": [7, 13], "next": [7, 15], "400b2723": 7, "eec5": 7, "422a": 7, "b7f3": 7, "236a0e10575b": 7, "23": [7, 8], "sep": 7, "14": 7, "42": 7, "cest": 7, "15": [7, 17], "healthcheck_rest": 7, "28169610": 7, "a969": 7, "4c20": 7, "9d11": 7, "ab7568b8a1bd": 7, "29": 7, "57": 7, "1m": 7, "recur": 7, "healhcheck": 7, "frontend": 7, "altern": [7, 9, 18], "prior": 7, "exist": [7, 8, 15, 17, 19], "interv": [7, 18], "1d": [7, 18], "weekli": [7, 18], "locat": [7, 14, 18], "s3": [7, 14, 18], "retent": [7, 18], "7d": [7, 18], "daili": [7, 18], "7": [7, 17], "configur": [7, 16, 18, 19], "consult": 7, "bucket": [7, 14, 18], "spot": 7, "275aae7f": 7, "c436": 7, "4fc8": 7, "bcec": 7, "479e65fb8372": 7, "58": 7, "d4946360": 7, "c29d": 7, "4bb4": 7, "8b9d": 7, "619ada495c2a": 7, "38": 7, "shortli": 7, "progress": [7, 9], "utc": 7, "durat": [7, 18], "69": 7, "system_auth": [7, 14], "06": [7, 17], "system_distribut": [7, 14], "00": 7, "system_trac": [7, 14], "present": 7, "my": [7, 18], "wasn": 7, "cannot": [7, 16], "due": [7, 10, 18], "lack": [7, 18], "target": [7, 16, 19], "62": [7, 13], "attempt": 7, "correct": [7, 9], "107": 7, "193": 7, "33": 7, "109": 7, "197": 7, "00000000": 7, "0000": 7, "000000000000": 7, "adhoc": 7, "retri": [7, 15, 18], "2b9dbe8c": 7, "9daa": 7, "4703": 7, "a66d": 7, "c29f63a917c8": 7, "infinit": 7, "resolv": [7, 15], "appear": 7, "kind": [8, 9, 16, 18, 19], "solv": [8, 19], "disambigu": [8, 19], "backward": [8, 19], "incompat": [8, 19], "involv": 8, "detach": 8, "scylla": [8, 9, 10, 12, 14, 16, 17], "period": 8, "noth": 8, "garbag": 8, "collect": [8, 9], "shouldn": [8, 13], "caus": [8, 12, 13, 15, 16], "downtim": 8, "consid": 8, "hacki": 8, "box": 8, "stage": [8, 15], "whole": [8, 15], "question": 8, "regard": 8, "welcom": 8, "slack": 8, "channel": 8, "sequenti": 8, "30m": [8, 19], "cert": 8, "anoth": 8, "offici": [8, 18], "websit": 8, "extract": [8, 14], "customresourcedefinit": [8, 19], "previou": [8, 15], "apivers": [8, 9, 16, 18, 19], "v1alpha1": [8, 9, 16, 19], "uuid": 8, "newli": 8, "metadata": [8, 9, 16, 18], "uid": 8, "12a3678d": 8, "8511": 8, "4c9c": 8, "8a48": 8, "fa78d3992694": 8, "somewher": 8, "might": [8, 13], "grant": 8, "lookup": 8, "patch": [8, 15, 19], "json": 8, "rule": 8, "apigroup": 8, "verb": 8, "amend": 8, "109m": 8, "96": 8, "66": 8, "22": [8, 17], "108m": 8, "246": 8, "106m": 8, "ownerrefer": 8, "column": 8, "lower": [8, 18], "110m": 8, "107m": 8, "st": [8, 19], "104m": 8, "bound": [8, 10, 13, 16], "old": [8, 13, 19], "boot": [8, 15], "600": 8, "initi": [8, 18], "initcontain": 8, "bump": 8, "introduc": [9, 16], "endpointsselector": 9, "matchlabel": 9, "ident": 9, "volumeclaimtempl": 9, "exposeopt": 9, "webinterfac": 9, "ingressclassnam": 9, "dnsdomain": 9, "annot": 9, "passthrough": 9, "explain": [9, 16, 18], "mai": [9, 10, 12, 13, 14, 15, 16, 17, 18, 19], "futur": 9, "third": 9, "parti": 9, "skip": 9, "5m": 9, "met": 9, "degrad": 9, "revis": 9, "65b89d55bb": 9, "outsid": 9, "recommend": [9, 19], "matter": 9, "packet": [9, 16], "tl": 9, "sni": 9, "caller": 9, "rout": 9, "properli": [9, 15, 19], "real": 9, "address": [9, 13, 14], "grafana_serving_cert": 9, "index": 9, "base64": 9, "d": [9, 14, 18, 19], "grafana_us": 9, "admin": 9, "usernam": [9, 14], "grafana_password": 9, "appropri": 9, "record": 9, "often": [9, 18], "wildcard": 9, "mydomain": 9, "cname": 9, "adjust": [9, 18], "similar": 9, "curl": 9, "dev": [9, 18], "null": 9, "w": 9, "http_code": 9, "cacert": 9, "echo": 9, "200": 9, "beyond": 9, "unless": 9, "assum": 9, "ingress_port": 9, "loadbalanc": 9, "reachabl": 9, "ingress_ip": 9, "slightli": [9, 18], "conveni": 9, "internal_ip": 9, "external_ip": 9, "rang": [9, 18], "item": 9, "eq": 9, "internalip": 9, "incid": 10, "explicit": 10, "becom": [10, 15, 17], "pvc": 10, "affin": 10, "automaticorphanednodecleanup": [10, 18], "flag": [10, 19], "hi": 10, "cleanup": [11, 15, 18], "lost": 11, "mainten": [11, 15], "restor": [11, 15, 19], "probe": [12, 19], "return": 12, "failur": [12, 13, 15, 18], "live": 12, "succe": 12, "load": [12, 13, 14, 18], "balanc": 12, "registri": 12, "stai": 12, "aliv": 12, "turn": [12, 15, 19], "bring": [12, 13, 15, 19], "back": [12, 13, 15], "front": 12, "east1": 12, "possibl": [13, 18], "stream": 13, "bandwidth": 13, "nodetool": 13, "c": [13, 14], "normal": 13, "leav": [13, 16], "join": 13, "move": [13, 15, 16], "token": [13, 18], "un": 13, "125": 13, "110": 13, "74": 13, "63": 13, "kb": 13, "256": 13, "8ebd6114": 13, "969c": 13, "44af": 13, "a978": 13, "87a4a6c65c3": 13, "189": 13, "91": 13, "03": [13, 17], "35d0cb19": 13, "35ef": 13, "482b": 13, "92a4": 13, "b63eee4527e5": 13, "77": 13, "1ffa7a82": 13, "c41c": 13, "4706": 13, "8f5f": 13, "4d45a39c7003": 13, "identifi": [13, 14], "3h12m": 13, "3h11m": 13, "3h5m": 13, "drain": [13, 15], "given": [13, 18], "b4b390a1": 13, "6j12": 13, "ignor": 13, "daemonset": [13, 16], "pend": 13, "3h21m": 13, "3h19m": 13, "8m14": 13, "recreat": [13, 14, 19], "3h27m": 13, "3h25m": 13, "9": [13, 14, 15, 17, 19], "store": [13, 14, 18], "visibl": 13, "191": 13, "172": 13, "sync": 13, "taken": [14, 15], "fresh": [14, 19], "snapshot": [14, 15, 18], "cluster_id": 14, "backup_loc": 14, "sm_20201227144037utc": 14, "409mib": 14, "sm_20201228145917utc": 14, "434mib": 14, "tabl": [14, 17, 18], "system_schema": [14, 15], "snapshot_tag": 14, "schema": [14, 15], "archiv": 14, "ed63b474": 14, "2c05": 14, "4f4f": 14, "b084": 14, "94541dd86e7a": 14, "task_287791d9": 14, "c257": 14, "4850": 14, "aef5": 14, "7537d6e69d90_tag_sm_20201228145917utc_schema": 14, "tar": 14, "gz": 14, "cp": 14, "ztvf": 14, "rw": 14, "12671": 14, "17": [14, 17], "2216": 14, "921": 14, "12567": 14, "4113": 14, "proce": 14, "backup_fil": 14, "sstableload": 14, "structur": 14, "temporari": 14, "cat": [14, 19], "awk": 14, "xarg": [14, 19], "n2": 14, "data_0": 14, "big": 14, "detect": 15, "semant": 15, "non": 15, "nightli": 15, "so_data_20201228135002utc": 15, "validate_upgrad": 15, "so_system_20201228135002utc": 15, "parallel": [15, 18], "underli": [15, 18], "ondelet": 15, "upgradestrategi": 15, "everi": [15, 17], "trace": 15, "displai": 15, "begin_upgrad": 15, "check_schema_agr": 15, "minut": 15, "create_system_backup": 15, "find_next_rack": 15, "decis": 15, "upgrade_image_in_pod_spec": 15, "find_next_nod": 15, "enable_maintenance_mod": 15, "drain_nod": 15, "backup_data": 15, "disable_maintenance_mod": 15, "delete_pod": 15, "clear_data_backup": 15, "clear_system_backup": 15, "restore_upgrade_strategi": 15, "finish_upgrad": 15, "recov": 15, "stuck": 15, "refus": 15, "replica": [15, 18], "zero": 15, "root": 15, "sstabl": 15, "left": [15, 18], "suppos": 16, "cover": 16, "placement": [16, 18], "perftun": 16, "optmiz": 16, "kernel": 16, "spread": 16, "irq": 16, "across": [16, 18], "assign": 16, "immedi": 16, "effic": 16, "pin": [16, 18, 19], "interrupt": 16, "One": 16, "context": 16, "switch": 16, "share": [16, 18], "coupl": 16, "daemon": 16, "entir": 16, "space": 16, "advantag": 16, "exclus": 16, "special": 16, "qo": 16, "doubl": 16, "meet": 16, "cf": 16, "quota": 16, "enforc": 16, "workload": 16, "around": 16, "howev": 16, "distribut": 16, "within": 16, "part": [16, 18], "fulfil": 16, "receiv": 16, "equal": [16, 18], "agentresourc": [16, 18], "500gi": 16, "1g": 16, "16g": 16, "aim": 17, "ship": 17, "approxim": 17, "week": 17, "advisori": 17, "hit": 17, "code": [17, 19], "freez": 17, "2022": 17, "08": 17, "2021": 17, "everyon": 17, "2023": 17, "07": 17, "04": 17, "11": 17, "01": 17, "05": 17, "21": 17, "elig": 17, "situat": 17, "assess": 17, "action": 17, "branch": [17, 19], "trigger": 17, "build": 17, "publish": 17, "artifact": 17, "e2": 17, "suit": 17, "vx": 17, "y": 17, "x": 17, "beta": [17, 18], "rc": 17, "ga": 17, "aren": 17, "scratch": [17, 19], "rather": 17, "candid": 17, "qualiti": 17, "qa": 17, "sing": 17, "sha": 17, "Be": 17, "function": 17, "gt": 17, "amp": 17, "lt": 17, "19": 17, "cri": 17, "v1alpha2": 17, "page": [18, 19], "intens": 18, "ratelimit": 18, "500g": 18, "storageclassnam": 18, "32gi": 18, "nodeaffin": 18, "requiredduringschedulingignoredduringexecut": 18, "nodeselectorterm": 18, "matchexpress": 18, "domain": 18, "effect": 18, "unset": 18, "agentrepositori": 18, "orphan": 18, "genericupgrad": 18, "failurestrategi": 18, "poll": 18, "sent": 18, "kube": 18, "apiserv": 18, "affect": 18, "overal": 18, "spent": 18, "scyllaarg": 18, "paramet": 18, "dnspolici": 18, "model": 18, "moment": 18, "schedul": 18, "human": 18, "readabl": 18, "uniqu": 18, "startdat": 18, "rfc3339": 18, "e": [18, 19], "3d2h10m": 18, "numretri": 18, "glob": 18, "dc1": 18, "otherdc": 18, "exclud": 18, "failfast": 18, "stop": 18, "shard": 18, "integ": 18, "higher": 18, "faster": 18, "impact": 18, "granular": 18, "resum": 18, "row": 18, "decim": 18, "percent": 18, "string": 18, "float": 18, "runtim": 18, "replic": 18, "factor": 18, "rf": 18, "formula": 18, "calcul": 18, "table_prefix_": 18, "smalltablethreshold": 18, "threshold": 18, "mib": 18, "tib": 18, "1gib": 18, "alphanumer": 18, "dot": 18, "charact": 18, "forbidden": 18, "gc": 18, "megabyt": 18, "snapshotparallel": 18, "global": 18, "uploadparallel": 18, "correspond": 18, "confus": 18, "storageclass": 18, "ram": 18, "minimum": 18, "amount": 18, "volum": 18, "volumemount": 18, "agentvolumemount": 18, "scyllaconfig": 18, "scyllaagentconfig": 18, "subfield": 18, "podaffin": 18, "podantiaffin": 18, "There": 19, "5871": 19, "7735": 19, "release_nam": 19, "tmpdir": 19, "mktemp": 19, "untar": 19, "untardir": 19, "printf": 19, "minor": 19, "symlink": 19, "expect": 19, "brought": 19, "lot": 19, "ones": 19, "mutatingwebhookconfigur": 19, "mutat": 19, "validatingwebhookconfigur": 19, "plane": 19, "95m": 19, "livenessprob": 19, "httpget": 19, "healthz": 19, "8080": 19, "scheme": 19, "readinessprob": 19, "retainkei": 19, "readyz": 19, "preserv": 19}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"contribut": 0, "scylla": [0, 1, 2, 3, 4, 5, 6, 7, 11, 13, 15, 18, 19], "oper": [0, 1, 2, 3, 4, 5, 9, 11, 19], "prerequisit": [0, 1, 2, 3, 4, 7, 9], "initi": [0, 2], "setup": [0, 1, 3], "creat": [0, 1, 2, 3], "fork": 0, "clone": 0, "your": 0, "add": 0, "upstream": 0, "remot": 0, "develop": 0, "build": 0, "project": 0, "branch": 0, "updat": 0, "submit": 0, "pull": 0, "request": 0, "commit": 0, "histori": 0, "messag": 0, "deploi": [1, 2, 3, 4, 7, 9], "ek": 1, "tl": [1, 3, 4], "dr": [1, 3, 4], "walkthrough": [1, 3], "configur": [1, 2, 3], "environ": [1, 3], "variabl": [1, 3], "an": [1, 9], "cluster": [1, 2, 3, 7, 18], "instal": [1, 3, 4], "script": 1, "third": 1, "parti": 1, "depend": 1, "set": [1, 2, 3, 18], "up": [1, 2, 3, 6, 7], "node": [1, 3, 10, 11, 13, 16], "scylladb": [1, 3], "local": [1, 2, 3], "volum": [1, 3], "provision": [1, 3], "access": [1, 2, 3, 9], "databas": [1, 2, 3], "delet": [1, 3], "kubernet": [2, 3, 7, 16], "run": 2, "download": 2, "cert": [2, 4], "manag": [2, 4, 6, 7, 9, 18], "host": 2, "network": 2, "contain": 2, "kernel": 2, "paramet": 2, "altern": 2, "agent": 2, "auth": 2, "token": 2, "monitor": [2, 4, 9], "scale": 2, "benchmark": 2, "cassandra": 2, "stress": 2, "down": 2, "clean": [2, 7], "troubleshoot": [2, 7], "gke": 3, "googl": 3, "engin": 3, "yourself": 3, "admin": 3, "stack": 4, "us": [4, 9, 11], "helm": [4, 19], "chart": 4, "repositori": 4, "imag": 4, "resourc": 4, "webhook": 4, "custom": 4, "control": 4, "result": 4, "cleanup": [4, 10], "document": 5, "known": 6, "issu": 6, "doe": 6, "boot": 6, "minikub": 6, "truncat": 6, "queri": 6, "work": 6, "architectur": 7, "registr": 7, "task": 7, "schedul": [7, 17], "version": [8, 15], "migrat": 8, "v0": [8, 19], "3": [8, 19], "0": [8, 19], "v1": [8, 19], "procedur": 8, "requir": 9, "prometheu": 9, "wait": 9, "roll": 9, "out": 9, "haproxi": 9, "ingress": 9, "scylladbmonitor": 9, "grafana": 9, "connect": 9, "through": 9, "resolv": 9, "domain": 9, "unresolv": 9, "variant": 9, "externalip": 9, "nodeport": 9, "automat": 10, "replac": [10, 13], "case": 10, "when": 10, "k8": 10, "i": 10, "lost": 10, "mainten": 12, "mode": 12, "dead": 13, "restor": 14, "from": 14, "backup": 14, "upgrad": [15, 19], "perform": 16, "tune": 16, "releas": 17, "support": 17, "backport": 17, "polici": 17, "ci": 17, "cd": 17, "autom": 17, "promot": 17, "gener": 17, "avail": 17, "matrix": 17, "crd": 18, "sampl": 18, "explan": 18, "datacent": 18, "rack": 18, "via": 19, "kubectl": 19, "2": 19, "1": 19}, "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": {"Replacing a Scylla node": [[13, "replacing-a-scylla-node"]], "Replacing a dead node": [[13, "replacing-a-dead-node"]], "Restore from backup": [[14, "restore-from-backup"]], "Automatic cleanup and replacement in case when k8s node is lost": [[10, "automatic-cleanup-and-replacement-in-case-when-k8s-node-is-lost"]], "Maintenance mode": [[12, "maintenance-mode"]], "Node operations using Scylla Operator": [[11, "node-operations-using-scylla-operator"]], "Deploying Scylla on EKS": [[1, "deploying-scylla-on-eks"]], "TL;DR;": [[1, "tl-dr"], [3, "tl-dr"]], "Walkthrough": [[1, "walkthrough"], [3, "walkthrough"]], "EKS Setup": [[1, "eks-setup"]], "Configure environment variables": [[1, "configure-environment-variables"], [3, "configure-environment-variables"]], "Creating an EKS cluster": [[1, "creating-an-eks-cluster"]], "Prerequisites": [[1, "prerequisites"], [2, "prerequisites"], [0, "prerequisites"], [4, "prerequisites"], [3, "prerequisites"], [7, "prerequisites"], [9, "prerequisites"]], "Installing script third party dependencies": [[1, "installing-script-third-party-dependencies"]], "Setting up nodes for ScyllaDB": [[1, "setting-up-nodes-for-scylladb"], [3, "setting-up-nodes-for-scylladb"]], "Deploying Local Volume Provisioner": [[1, "deploying-local-volume-provisioner"], [3, "deploying-local-volume-provisioner"]], "Installing the Scylla Operator and Scylla": [[1, "installing-the-scylla-operator-and-scylla"], [3, "installing-the-scylla-operator-and-scylla"]], "Accessing the database": [[1, "accessing-the-database"], [3, "accessing-the-database"]], "Deleting an EKS cluster": [[1, "deleting-an-eks-cluster"]], "Deploying Scylla on a Kubernetes Cluster": [[2, "deploying-scylla-on-a-kubernetes-cluster"]], "Running locally": [[2, "running-locally"]], "Download Scylla Operator": [[2, "download-scylla-operator"]], "Deploy Cert Manager": [[2, "deploy-cert-manager"], [4, "deploy-cert-manager"]], "Deploy Scylla Operator": [[2, "deploy-scylla-operator"]], "Create and Initialize a Scylla Cluster": [[2, "create-and-initialize-a-scylla-cluster"]], "Configure host networking": [[2, "configure-host-networking"]], "Configure container kernel parameters": [[2, "configure-container-kernel-parameters"]], "Deploying Alternator": [[2, "deploying-alternator"]], "Accessing the Database": [[2, "accessing-the-database"]], "Configure Scylla": [[2, "configure-scylla"]], "Configure Scylla Manager Agent": [[2, "configure-scylla-manager-agent"]], "Scylla Manager Agent auth token": [[2, "scylla-manager-agent-auth-token"]], "Set up monitoring": [[2, "set-up-monitoring"]], "Scale Up": [[2, "scale-up"]], "Benchmark with cassandra-stress": [[2, "benchmark-with-cassandra-stress"]], "Scale Down": [[2, "scale-down"]], "Clean Up": [[2, "clean-up"], [7, "clean-up"]], "Troubleshooting": [[2, "troubleshooting"], [7, "troubleshooting"]], "Contributing to Scylla Operator": [[0, "contributing-to-scylla-operator"]], "Initial Setup": [[0, "initial-setup"]], "Create a Fork": [[0, "create-a-fork"]], "Clone Your Fork": [[0, "clone-your-fork"]], "Add Upstream Remote": [[0, "add-upstream-remote"]], "Development": [[0, "development"]], "Building the project": [[0, "building-the-project"]], "Create a Branch": [[0, "create-a-branch"]], "Updating Your Fork": [[0, "updating-your-fork"]], "Submitting a Pull Request": [[0, "submitting-a-pull-request"]], "Commit History": [[0, "commit-history"]], "Commit messages": [[0, "commit-messages"]], "Submitting": [[0, "submitting"]], "Deploying Scylla stack using Helm Charts": [[4, "deploying-scylla-stack-using-helm-charts"]], "TL;DR": [[4, "tl-dr"]], "Helm Chart repository": [[4, "helm-chart-repository"]], "Scylla Operator Chart": [[4, "scylla-operator-chart"]], "image": [[4, "image"]], "resources": [[4, "resources"]], "webhook": [[4, "webhook"]], "Customization": [[4, "customization"], [4, "id1"], [4, "id3"]], "Installation": [[4, "installation"], [4, "id2"], [4, "id4"]], "Scylla Helm Chart": [[4, "scylla-helm-chart"]], "Scylla Manager Helm Chart": [[4, "scylla-manager-helm-chart"]], "Scylla Manager": [[4, "scylla-manager"]], "Scylla Manager Controller": [[4, "scylla-manager-controller"]], "Scylla": [[4, "scylla"]], "Results": [[4, "results"]], "Monitoring": [[4, "monitoring"], [9, "monitoring"]], "Cleanup": [[4, "cleanup"]], "Deploying Scylla on GKE": [[3, "deploying-scylla-on-gke"]], "Google Kubernetes Engine Setup": [[3, "google-kubernetes-engine-setup"]], "Creating a GKE cluster": [[3, "creating-a-gke-cluster"]], "Setting Yourself as cluster-admin": [[3, "setting-yourself-as-cluster-admin"]], "Deploy Scylla cluster": [[3, "deploy-scylla-cluster"]], "Deleting a GKE cluster": [[3, "deleting-a-gke-cluster"]], "Scylla Operator Documentation": [[5, "scylla-operator-documentation"]], "Deploying Scylla Manager on a Kubernetes Cluster": [[7, "deploying-scylla-manager-on-a-kubernetes-cluster"]], "Architecture": [[7, "architecture"]], "Deploy Scylla Manager": [[7, "deploy-scylla-manager"]], "Cluster registration": [[7, "cluster-registration"]], "Task scheduling": [[7, "task-scheduling"]], "Known issues": [[6, "known-issues"]], "Scylla Manager does not boot up on Minikube": [[6, "scylla-manager-does-not-boot-up-on-minikube"]], "TRUNCATE queries does not work on Minikube": [[6, "truncate-queries-does-not-work-on-minikube"]], "Version migrations": [[8, "version-migrations"]], "v0.3.0 -> v1.0.0 migration": [[8, "v0-3-0-v1-0-0-migration"]], "Procedure": [[8, "procedure"]], "Deploy managed monitoring": [[9, "deploy-managed-monitoring"]], "Requirements": [[9, "requirements"]], "Deploy Prometheus Operator": [[9, "deploy-prometheus-operator"]], "Wait for Prometheus Operator to roll out": [[9, "wait-for-prometheus-operator-to-roll-out"]], "Deploy HAProxy Ingress": [[9, "deploy-haproxy-ingress"]], "Wait for HAProxy Ingress to roll out": [[9, "wait-for-haproxy-ingress-to-roll-out"]], "Deploy ScyllaDBMonitoring": [[9, "deploy-scylladbmonitoring"]], "Wait for ScyllaDBMonitoring to roll out": [[9, "wait-for-scylladbmonitoring-to-roll-out"]], "Wait for Prometheus to roll out": [[9, "wait-for-prometheus-to-roll-out"]], "Wait for Grafana to roll out": [[9, "wait-for-grafana-to-roll-out"]], "Accessing Grafana": [[9, "accessing-grafana"]], "Connecting through Ingress using a resolvable domain": [[9, "connecting-through-ingress-using-a-resolvable-domain"]], "Connecting through Ingress using an unresolvable domain": [[9, "connecting-through-ingress-using-an-unresolvable-domain"]], "Variants": [[9, "variants"]], "Ingress ExternalIP": [[9, "ingress-externalip"]], "Ingress NodePort": [[9, "ingress-nodeport"]], "Connection": [[9, "connection"]], "Upgrade of Scylla Operator": [[19, "upgrade-of-scylla-operator"]], "Upgrade via Helm": [[19, "upgrade-via-helm"]], "Upgrade via kubectl": [[19, "upgrade-via-kubectl"]], "v1.2.0 -> v1.3.0": [[19, "v1-2-0-v1-3-0"]], "v1.1.0 -> v1.2.0": [[19, "v1-1-0-v1-2-0"]], "v1.0.0 -> v1.1.0": [[19, "v1-0-0-v1-1-0"]], "v0.3.0 -> v1.0.0": [[19, "v0-3-0-v1-0-0"]], "Scylla Cluster CRD": [[18, "scylla-cluster-crd"]], "Sample": [[18, "sample"]], "Settings Explanation": [[18, "settings-explanation"]], "Cluster Settings": [[18, "cluster-settings"]], "Scylla Manager settings": [[18, "scylla-manager-settings"]], "Datacenter Settings": [[18, "datacenter-settings"]], "Rack Settings": [[18, "rack-settings"]], "Releases": [[17, "releases"]], "Schedule": [[17, "schedule"]], "Supported releases": [[17, "supported-releases"]], "Backport policy": [[17, "backport-policy"]], "CI/CD": [[17, "ci-cd"]], "Automated promotions": [[17, "automated-promotions"]], "Generally available": [[17, "generally-available"]], "Support matrix": [[17, "support-matrix"]], "Upgrading version of Scylla": [[15, "upgrading-version-of-scylla"]], "Performance tuning": [[16, "performance-tuning"]], "Node tuning": [[16, "node-tuning"]], "Kubernetes tuning": [[16, "kubernetes-tuning"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/v1.10/sitemap.xml b/v1.10/sitemap.xml new file mode 100644 index 00000000000..b8da8fc0b01 --- /dev/null +++ b/v1.10/sitemap.xml @@ -0,0 +1,2 @@ + +https://operator.docs.scylladb.com/stable/contributing.htmlhttps://operator.docs.scylladb.com/stable/eks.htmlhttps://operator.docs.scylladb.com/stable/generic.htmlhttps://operator.docs.scylladb.com/stable/gke.htmlhttps://operator.docs.scylladb.com/stable/manager.htmlhttps://operator.docs.scylladb.com/stable/helm.htmlhttps://operator.docs.scylladb.com/stable/index.htmlhttps://operator.docs.scylladb.com/stable/known-issues.htmlhttps://operator.docs.scylladb.com/stable/migration.htmlhttps://operator.docs.scylladb.com/stable/monitoring.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/automatic-cleanup.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/index.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/maintenance-mode.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/replace-node.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/restore.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/scylla-upgrade.htmlhttps://operator.docs.scylladb.com/stable/upgrade.htmlhttps://operator.docs.scylladb.com/stable/performance.htmlhttps://operator.docs.scylladb.com/stable/releases.htmlhttps://operator.docs.scylladb.com/stable/scylla-cluster-crd.htmlhttps://operator.docs.scylladb.com/stable/genindex.htmlhttps://operator.docs.scylladb.com/stable/404.htmlhttps://operator.docs.scylladb.com/stable/search.html \ No newline at end of file diff --git a/v1.10/upgrade.html b/v1.10/upgrade.html new file mode 100644 index 00000000000..b0dab7a0c8f --- /dev/null +++ b/v1.10/upgrade.html @@ -0,0 +1,781 @@ + + + + + + + + + + + + + Upgrade of Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Upgrade of Scylla Operator

          +

          This page describes Scylla Operator upgrade procedures.
          There are two generic update procedures - via Helm and via kubectl. Before upgrading, please check this page to find out +if your target version requires additional upgrade steps.

          +
          +

          Upgrade via Helm

          +

          Helm doesn’t support managing CustomResourceDefinition resources (#5871, #7735)
          These are only created on first install and never updated. In order to update them, users have to do it manually.

          +

          Replace <release_name> with the name of your Helm release for Scylla Operator and replace <version> with the version number you want to install:

          +
            +
          1. Make sure Helm chart repository is up-to-date:

            +
            helm repo add scylla-operator https://storage.googleapis.com/scylla-operator-charts/stable
            +helm repo update
            +
            +
            +
          2. +
          3. Update CRD resources. We recommend using --server-side flag for kubectl apply, if your version supports it.

            +
            tmpdir=$( mktemp -d ) \
            +  && helm pull scylla-operator/scylla-operator --version <version> --untar --untardir "${tmpdir}" \
            +  && find "${tmpdir}"/scylla-operator/crds/ -name '*.yaml' -printf '-f=%p ' \
            +  | xargs kubectl apply
            +
            +
            +
          4. +
          5. Update Scylla Operator

            +
            helm upgrade --version <version> <release_name> scylla-operator/scylla-operator
            +
            +
            +
          6. +
          +
          +
          +

          Upgrade via kubectl

          +

          Replace <version> with the version number you want to install:

          +
            +
          1. Checkout source code of version you want to use:

            +
            git checkout <version>
            +
            +
            +
          2. +
          3. Manifests use rolling minor version tag, you may want to pin it to specific version:

            +
            find deploy/operator -name "*.yaml" | xargs sed --follow-symlinks -i -E "s^docker.io/scylladb/scylla-operator:[0-9]+\.[0-9]+^docker.io/scylladb/scylla-operator:<version>^g"
            +
            +
            +
          4. +
          5. Update Scylla Operator. We recommend using --server-side flag for kubectl apply, if your version supports it.

            +
            kubectl apply -f deploy/operator
            +
            +
            +
          6. +
          +
          +
          +
          +

          v1.2.0 -> v1.3.0

          +

          Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

          +
            +
          1. Checkout source code of v1.3.0:

            +
            git checkout v1.3.0
            +
            +
            +
          2. +
          3. Update Scylla Operator from deploy directory:

            +
            kubectl -n scylla-operator apply -f deploy/operator
            +
            +
            +
          4. +
          5. Wait until Scylla Operator is up and running:

            +
            kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
            +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
            +
            +
            +
          6. +
          +
          +
          +

          v1.1.0 -> v1.2.0

          +

          1.2.0 release brought a lot of changes to the Scylla Operator deployment process. +To properly update Scylla Operator one must delete old objects and install updated ones.

          +

          Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

          +
            +
          1. Checkout source code of v1.2.0:

            +
            git checkout v1.2.0
            +
            +
            +
          2. +
          3. Remove old scylla operator namespace - in our case it’s called scylla-operator-system:

            +
            kubectl delete namespace scylla-operator-system --wait=true
            +
            +
            +
          4. +
          5. Remove old webhooks:

            +
            kubectl delete MutatingWebhookConfiguration scylla-operator-mutating-webhook-configuration
            +kubectl delete ValidatingWebhookConfiguration scylla-operator-validating-webhook-configuration
            +
            +
            +
          6. +
          7. Install Scylla Operator from deploy directory:

            +
            kubectl -n scylla-operator apply -f deploy/operator
            +
            +
            +
          8. +
          9. Wait until Scylla Operator is up and running:

            +
            kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
            +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
            +
            +
            +
          10. +
          +
          +
          +

          v1.0.0 -> v1.1.0

          +

          During this update we will change probes and image for Scylla Operator. +A new version brings an automation for upgrade of sidecar image, so a rolling restart of managed Scylla clusters is expected.

          +
            +
          1. Get name of StatefulSet managing Scylla Operator

            +
            kubectl --namespace scylla-operator-system get sts --selector="control-plane=controller-manager"
            +
            +NAME                                 READY   AGE
            +scylla-operator-controller-manager   1/1     95m
            +
            +
            +
          2. +
          3. Change probes and used container image by applying following patch:

            +
            spec:
            +  template:
            +    spec:
            +      containers:
            +      - name: manager
            +        image: docker.io/scylladb/scylla-operator:1.1.0
            +        livenessProbe:
            +          httpGet:
            +            path: /healthz
            +            port: 8080
            +            scheme: HTTP
            +        readinessProbe:
            +          $retainKeys:
            +          - httpGet
            +          httpGet:
            +            path: /readyz
            +            port: 8080
            +            scheme: HTTP
            +
            +
            +

            To apply above patch save it to file (operator-patch.yaml for example) and apply to Operator StatefulSet:

            +
            kubectl -n scylla-operator-system patch sts scylla-operator-controller-manager --patch "$(cat operator-patch.yaml)"
            +
            +
            +
          4. +
          +
          +
          +

          v0.3.0 -> v1.0.0

          +

          Note: There’s an experimental migration procedure available here.

          +

          v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common +kind which is easier to disambiguate. (ScyllaCluster). +This change is backward incompatible, so Scylla cluster must be turned off and recreated from scratch. +In case you need to preserve your data, refer to backup and restore guide.

          +
            +
          1. Get list of existing Scylla clusters

            +
            kubectl -n scylla get cluster.scylla.scylladb.com
            +
            +NAME             AGE
            +simple-cluster   30m
            +
            +
            +
          2. +
          3. Delete each one of them

            +
            kubectl -n scylla delete cluster.scylla.scylladb.com simple-cluster
            +
            +
            +
          4. +
          5. Make sure you’re on v0.3.0 branch

            +
            git checkout v0.3.0
            +
            +
            +
          6. +
          7. Delete existing CRD and Operator

            +
            kubectl delete -f examples/generic/operator.yaml
            +
            +
            +
          8. +
          9. Checkout v1.0.0 version

            +
            git checkout v1.0.0
            +
            +
            +
          10. +
          11. Install new CRD and Scylla Operator

            +
            kubectl apply -f examples/common/operator.yaml
            +
            +
            +
          12. +
          13. Migrate your existing Scylla Cluster definition. Change apiVersion and kind from:

            +
            apiVersion: scylla.scylladb.com/v1alpha1
            +kind: Cluster
            +
            +
            +

            to:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +
            +
            +
          14. +
          15. Once your cluster definition is ready, use kubectl apply to install fresh Scylla cluster.

          16. +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v1.11/.buildinfo b/v1.11/.buildinfo new file mode 100644 index 00000000000..ca144966e8a --- /dev/null +++ b/v1.11/.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: a7e55cbf26668b392cfc9fabddb97157 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/v1.11/.doctrees/contributing.doctree b/v1.11/.doctrees/contributing.doctree new file mode 100644 index 00000000000..383c89e83bb Binary files /dev/null and b/v1.11/.doctrees/contributing.doctree differ diff --git a/v1.11/.doctrees/eks.doctree b/v1.11/.doctrees/eks.doctree new file mode 100644 index 00000000000..d1356dcd6d5 Binary files /dev/null and b/v1.11/.doctrees/eks.doctree differ diff --git a/v1.11/.doctrees/environment.pickle b/v1.11/.doctrees/environment.pickle new file mode 100644 index 00000000000..3484c7911d0 Binary files /dev/null and b/v1.11/.doctrees/environment.pickle differ diff --git a/v1.11/.doctrees/exposing.doctree b/v1.11/.doctrees/exposing.doctree new file mode 100644 index 00000000000..1402c618cb0 Binary files /dev/null and b/v1.11/.doctrees/exposing.doctree differ diff --git a/v1.11/.doctrees/generic.doctree b/v1.11/.doctrees/generic.doctree new file mode 100644 index 00000000000..e4c33ccbe98 Binary files /dev/null and b/v1.11/.doctrees/generic.doctree differ diff --git a/v1.11/.doctrees/gke.doctree b/v1.11/.doctrees/gke.doctree new file mode 100644 index 00000000000..363af21e0d5 Binary files /dev/null and b/v1.11/.doctrees/gke.doctree differ diff --git a/v1.11/.doctrees/helm.doctree b/v1.11/.doctrees/helm.doctree new file mode 100644 index 00000000000..072325f9e01 Binary files /dev/null and b/v1.11/.doctrees/helm.doctree differ diff --git a/v1.11/.doctrees/index.doctree b/v1.11/.doctrees/index.doctree new file mode 100644 index 00000000000..28cfaf18306 Binary files /dev/null and b/v1.11/.doctrees/index.doctree differ diff --git a/v1.11/.doctrees/manager.doctree b/v1.11/.doctrees/manager.doctree new file mode 100644 index 00000000000..112c48cb31c Binary files /dev/null and b/v1.11/.doctrees/manager.doctree differ diff --git a/v1.11/.doctrees/migration.doctree b/v1.11/.doctrees/migration.doctree new file mode 100644 index 00000000000..8fabad70fd2 Binary files /dev/null and b/v1.11/.doctrees/migration.doctree differ diff --git a/v1.11/.doctrees/monitoring.doctree b/v1.11/.doctrees/monitoring.doctree new file mode 100644 index 00000000000..feac013e77e Binary files /dev/null and b/v1.11/.doctrees/monitoring.doctree differ diff --git a/v1.11/.doctrees/multidc/eks.doctree b/v1.11/.doctrees/multidc/eks.doctree new file mode 100644 index 00000000000..b7c9bc6035d Binary files /dev/null and b/v1.11/.doctrees/multidc/eks.doctree differ diff --git a/v1.11/.doctrees/multidc/gke.doctree b/v1.11/.doctrees/multidc/gke.doctree new file mode 100644 index 00000000000..cd2da52e8e1 Binary files /dev/null and b/v1.11/.doctrees/multidc/gke.doctree differ diff --git a/v1.11/.doctrees/multidc/index.doctree b/v1.11/.doctrees/multidc/index.doctree new file mode 100644 index 00000000000..c7f658485a2 Binary files /dev/null and b/v1.11/.doctrees/multidc/index.doctree differ diff --git a/v1.11/.doctrees/multidc/multidc.doctree b/v1.11/.doctrees/multidc/multidc.doctree new file mode 100644 index 00000000000..77d540ba620 Binary files /dev/null and b/v1.11/.doctrees/multidc/multidc.doctree differ diff --git a/v1.11/.doctrees/nodeoperations/automatic-cleanup.doctree b/v1.11/.doctrees/nodeoperations/automatic-cleanup.doctree new file mode 100644 index 00000000000..99a6ba52b53 Binary files /dev/null and b/v1.11/.doctrees/nodeoperations/automatic-cleanup.doctree differ diff --git a/v1.11/.doctrees/nodeoperations/index.doctree b/v1.11/.doctrees/nodeoperations/index.doctree new file mode 100644 index 00000000000..97e2fc5f4a9 Binary files /dev/null and b/v1.11/.doctrees/nodeoperations/index.doctree differ diff --git a/v1.11/.doctrees/nodeoperations/maintenance-mode.doctree b/v1.11/.doctrees/nodeoperations/maintenance-mode.doctree new file mode 100644 index 00000000000..ee7053fc197 Binary files /dev/null and b/v1.11/.doctrees/nodeoperations/maintenance-mode.doctree differ diff --git a/v1.11/.doctrees/nodeoperations/replace-node.doctree b/v1.11/.doctrees/nodeoperations/replace-node.doctree new file mode 100644 index 00000000000..44d903063ee Binary files /dev/null and b/v1.11/.doctrees/nodeoperations/replace-node.doctree differ diff --git a/v1.11/.doctrees/nodeoperations/restore.doctree b/v1.11/.doctrees/nodeoperations/restore.doctree new file mode 100644 index 00000000000..f98972c2ae1 Binary files /dev/null and b/v1.11/.doctrees/nodeoperations/restore.doctree differ diff --git a/v1.11/.doctrees/nodeoperations/scylla-upgrade.doctree b/v1.11/.doctrees/nodeoperations/scylla-upgrade.doctree new file mode 100644 index 00000000000..980a53e217e Binary files /dev/null and b/v1.11/.doctrees/nodeoperations/scylla-upgrade.doctree differ diff --git a/v1.11/.doctrees/performance.doctree b/v1.11/.doctrees/performance.doctree new file mode 100644 index 00000000000..d18f60d4f59 Binary files /dev/null and b/v1.11/.doctrees/performance.doctree differ diff --git a/v1.11/.doctrees/releases.doctree b/v1.11/.doctrees/releases.doctree new file mode 100644 index 00000000000..0e405985882 Binary files /dev/null and b/v1.11/.doctrees/releases.doctree differ diff --git a/v1.11/.doctrees/scylla-cluster-crd.doctree b/v1.11/.doctrees/scylla-cluster-crd.doctree new file mode 100644 index 00000000000..cefa778bf49 Binary files /dev/null and b/v1.11/.doctrees/scylla-cluster-crd.doctree differ diff --git a/v1.11/.doctrees/support/index.doctree b/v1.11/.doctrees/support/index.doctree new file mode 100644 index 00000000000..024eaf45c62 Binary files /dev/null and b/v1.11/.doctrees/support/index.doctree differ diff --git a/v1.11/.doctrees/support/known-issues.doctree b/v1.11/.doctrees/support/known-issues.doctree new file mode 100644 index 00000000000..5a1553e35a1 Binary files /dev/null and b/v1.11/.doctrees/support/known-issues.doctree differ diff --git a/v1.11/.doctrees/support/must-gather.doctree b/v1.11/.doctrees/support/must-gather.doctree new file mode 100644 index 00000000000..c0b4667a8d7 Binary files /dev/null and b/v1.11/.doctrees/support/must-gather.doctree differ diff --git a/v1.11/.doctrees/support/overview.doctree b/v1.11/.doctrees/support/overview.doctree new file mode 100644 index 00000000000..16ad04ebc0c Binary files /dev/null and b/v1.11/.doctrees/support/overview.doctree differ diff --git a/v1.11/.doctrees/support/troubleshooting/index.doctree b/v1.11/.doctrees/support/troubleshooting/index.doctree new file mode 100644 index 00000000000..8f579834b91 Binary files /dev/null and b/v1.11/.doctrees/support/troubleshooting/index.doctree differ diff --git a/v1.11/.doctrees/support/troubleshooting/installation.doctree b/v1.11/.doctrees/support/troubleshooting/installation.doctree new file mode 100644 index 00000000000..51f268af8f4 Binary files /dev/null and b/v1.11/.doctrees/support/troubleshooting/installation.doctree differ diff --git a/v1.11/.doctrees/upgrade.doctree b/v1.11/.doctrees/upgrade.doctree new file mode 100644 index 00000000000..677cdd4c224 Binary files /dev/null and b/v1.11/.doctrees/upgrade.doctree differ diff --git a/v1.11/.nojekyll b/v1.11/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/v1.11/404.html b/v1.11/404.html new file mode 100644 index 00000000000..067dc99ea74 --- /dev/null +++ b/v1.11/404.html @@ -0,0 +1,31 @@ + + + + + + + + + ScyllaDB + + + + + + + + + + + +
          +

          404

          +

          The ScyllaDB monster ate your page!

          +

          + Home +

          +
          + + + \ No newline at end of file diff --git a/v1.11/CNAME b/v1.11/CNAME new file mode 100644 index 00000000000..12aae904168 --- /dev/null +++ b/v1.11/CNAME @@ -0,0 +1 @@ +operator.docs.scylladb.com \ No newline at end of file diff --git a/v1.11/_images/clusterip.svg b/v1.11/_images/clusterip.svg new file mode 100644 index 00000000000..1c74e5e69ba --- /dev/null +++ b/v1.11/_images/clusterip.svg @@ -0,0 +1,3 @@ + + +
          Service
          ClusterIP
          10.0.0.1
          Servi...
          Service
          ClusterIP
          10.0.0.2
          Servi...
          Service
          ClusterIP
          10.0.0.3
          Servi...
          Pod
          Client
          Pod...
          Kubernetes cluster
          Kubernetes cluster
          Text is not SVG - cannot display
          \ No newline at end of file diff --git a/v1.11/_images/loadbalancer.svg b/v1.11/_images/loadbalancer.svg new file mode 100644 index 00000000000..c86a9a2a46b --- /dev/null +++ b/v1.11/_images/loadbalancer.svg @@ -0,0 +1,3 @@ + + +
          Service
          LoadBalancer
          Servi...
          Service
          LoadBalancer
          Servi...
          Service
          LoadBalancer
          Servi...
          Kubernetes cluster
          Kubernetes cluster
          VPC
          VPC
          Cloud Load
          Balancing
          Cloud...
          Cloud Load
          Balancing
          Cloud...
          Cloud Load
          Balancing
          Cloud...
          Client
          Client
          Internet
          Internet
          Text is not SVG - cannot display
          \ No newline at end of file diff --git a/v1.11/_images/logo.png b/v1.11/_images/logo.png new file mode 100644 index 00000000000..5bbfedad2ac Binary files /dev/null and b/v1.11/_images/logo.png differ diff --git a/v1.11/_images/multivpc.svg b/v1.11/_images/multivpc.svg new file mode 100644 index 00000000000..96fdcd7a536 --- /dev/null +++ b/v1.11/_images/multivpc.svg @@ -0,0 +1,3 @@ + + +
          Kubernetes cluster
          Kubernetes cluster
          Virtual Machine
          Client
          10.0.0.4
          Virtu...
          VPC A
          VPC A
          Pod
          Client
          20.0.0.5
          Pod...
          Kubernetes cluster
          Kubernetes cluster
          Virtual Machine
          Client
          20.0.0.4
          Virtu...
          VPC B
          VPC B
          Pod
          Client
          10.0.0.5
          Pod...
          VPC Peering
          VPC Peering


          Service
          Headless
          Service...


          Service
          Headless
          Service...


          Service
          Headless
          Service...


          Service
          Headless
          Service...


          Service
          Headless
          Service...


          Service
          Headless
          Service...
          PodIP: 10.0.0.3
          PodIP: 10.0.0...
          PodIP: 10.0.0.2
          PodIP: 10.0.0...
          PodIP: 10.0.0.1
          PodIP: 10.0.0...
          PodIP: 20.0.0.1
          PodIP: 20.0.0...
          PodIP: 20.0.0.2
          PodIP: 20.0.0...
          PodIP: 20.0.0.1
          PodIP: 20.0.0...
          Text is not SVG - cannot display
          \ No newline at end of file diff --git a/v1.11/_images/podips.svg b/v1.11/_images/podips.svg new file mode 100644 index 00000000000..03f1a44c7d6 --- /dev/null +++ b/v1.11/_images/podips.svg @@ -0,0 +1,3 @@ + + +
          Service
          ClusterIP
          10.0.0.1
          Servi...
          Service
          ClusterIP
          10.0.0.2
          Servi...
          Service
          ClusterIP
          10.0.0.3
          Servi...
          Pod
          Client
          20.0.0.5
          Pod...
          Kubernetes cluster
          Kubernetes cluster
          Virtual Machine
          Client
          20.0.0.4
          Virtu...
          PodIP: 20.0.0.1
          PodIP: 20.0.0...
          PodIP: 20.0.0.2
          PodIP: 20.0.0...
          PodIP: 20.0.0.3
          PodIP: 20.0.0...
          VPC
          VPC
          Text is not SVG - cannot display
          \ No newline at end of file diff --git a/v1.11/_sources/contributing.md.txt b/v1.11/_sources/contributing.md.txt new file mode 100644 index 00000000000..da5fc078732 --- /dev/null +++ b/v1.11/_sources/contributing.md.txt @@ -0,0 +1,155 @@ +# Contributing to Scylla Operator + +## Prerequisites + +To develop on scylla-operator, your environment must have the following: + +1. [Go 1.13](https://golang.org/dl/) + * Make sure [GOPATH](https://github.com/golang/go/wiki/SettingGOPATH) is set to `GOPATH=$HOME/go`. +2. [Kustomize v3.1.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/v3.1.0) +3. [kubebuilder v2.3.1](https://github.com/kubernetes-sigs/kubebuilder/releases/tag/v2.3.1) +4. [Docker](https://docs.docker.com/install/) +5. Git client installed +6. Github account + +To install all dependencies (Go, kustomize, kubebuilder, dep), simply run: +```bash +./install-dependencies.sh +``` + +## Initial Setup + +### Create a Fork + +From your browser navigate to [http://github.com/scylladb/scylla-operator](http://github.com/scylladb/scylla-operator) and click the "Fork" button. + +### Clone Your Fork + +Open a console window and do the following: + +```bash +# Create the scylla operator repo path +mkdir -p $GOPATH/src/github.com/scylladb + +# Navigate to the local repo path and clone your fork +cd $GOPATH/src/github.com/scylladb + +# Clone your fork, where is your GitHub account name +git clone https://github.com//scylla-operator.git +``` + +### Add Upstream Remote + +First you will need to add the upstream remote to your local git: +```bash +# Add 'upstream' to the list of remotes +git remote add upstream https://github.com/scylladb/scylla-operator.git + +# Verify the remote was added +git remote -v +``` +Now you should have at least `origin` and `upstream` remotes. You can also add other remotes to collaborate with other contributors. + +## Development + +To add a feature or to make a bug fix, you will need to create a branch in your fork and then submit a pull request (PR) from the branch. + +### Building the project + +You can build the project using the Makefile commands: +* Open the Makefile and change the `IMG` environment variable to a repository you have access to. +* Run `make docker-push` and wait for the image to be built and uploaded in your repo. + +### Create a Branch + +From a console, create a new branch based on your fork and start working on it: + +```bash +# Ensure all your remotes are up to date with the latest +git fetch --all + +# Create a new branch that is based off upstream master. Give it a simple, but descriptive name. +# Generally it will be two to three words separated by dashes and without numbers. +git checkout -b feature-name upstream/master +``` + +Now you are ready to make the changes and commit to your branch. + +### Updating Your Fork + +During the development lifecycle, you will need to keep up-to-date with the latest upstream master. As others on the team push changes, you will need to `rebase` your commits on top of the latest. This avoids unnecessary merge commits and keeps the commit history clean. + +Whenever you need to update your local repository, you never want to merge. You **always** will rebase. Otherwise you will end up with merge commits in the git history. If you have any modified files, you will first have to stash them (`git stash save -u ""`). + +```bash +git fetch --all +git rebase upstream/master +``` + +Rebasing is a very powerful feature of Git. You need to understand how it works or else you will risk losing your work. Read about it in the [Git documentation](https://git-scm.com/docs/git-rebase), it will be well worth it. In a nutshell, rebasing does the following: +- "Unwinds" your local commits. Your local commits are removed temporarily from the history. +- The latest changes from upstream are added to the history +- Your local commits are re-applied one by one +- If there are merge conflicts, you will be prompted to fix them before continuing. Read the output closely. It will tell you how to complete the rebase. +- When done rebasing, you will see all of your commits in the history. + +## Submitting a Pull Request + +Once you have implemented the feature or bug fix in your branch, you will open a PR to the upstream repo. Before opening the PR ensure you have added unit tests, are passing the integration tests, cleaned your commit history, and have rebased on the latest upstream. + +In order to open a pull request (PR) it is required to be up to date with the latest changes upstream. If other commits are pushed upstream before your PR is merged, you will also need to rebase again before it will be merged. + +### Commit History + +To prepare your branch to open a PR, you will need to have the minimal number of logical commits so we can maintain +a clean commit history. Most commonly a PR will include a single commit where all changes are squashed, although +sometimes there will be multiple logical commits. + +```bash +# Inspect your commit history to determine if you need to squash commits +git log + +# Rebase the commits and edit, squash, or even reorder them as you determine will keep the history clean. +# In this example, the last 5 commits will be opened in the git rebase tool. +git rebase -i HEAD~5 +``` + +Once your commit history is clean, ensure you have based on the [latest upstream](#updating-your-fork) before you open the PR. + +### Commit messages + +Please make the first line of your commit message a summary of the change that a user (not a developer) of Operator would like to read, +and prefix it with the most relevant directory of the change followed by a colon. +The changelog gets made by looking at just these first lines so make it good! + +If you have more to say about the commit, then enter a blank line and carry on the description. +Remember to say why the change was needed - the commit itself shows what was changed. + +Writing more is better than less. Comparing the behaviour before the change to that after the change is very useful. +Imagine you are writing to yourself in 12 months time when you've forgotten everything about what you just did, and you need to get up to speed quickly. + +If the change fixes an issue then write Fixes #1234 in the commit message. +This can be on the subject line if it will fit. If you don't want to close the associated issue just put #1234 and the change will get linked into the issue. + +Here is an example of a short commit message: + +``` +sidecar: log on reconcile loop - fixes #1234 +``` + +And here is an example of a longer one: +``` + +api: now supports host networking (#1234) + +The operator CRD now has a "network" property that can be used to +select host networking as well as setting the apropriate DNS policy. + +Fixes #1234 +``` + +### Submitting + +Go to the [Scylla Operator github](https://www.github.com/scylladb/scylla-operator) to open the PR. If you have pushed recently, you should see an obvious link to open the PR. If you have not pushed recently, go to the Pull Request tab and select your fork and branch for the PR. + +After the PR is open, you can make changes simply by pushing new commits. Your PR will track the changes in your fork and update automatically. diff --git a/v1.11/_sources/eks.md.txt b/v1.11/_sources/eks.md.txt new file mode 100644 index 00000000000..8f8c6b931d3 --- /dev/null +++ b/v1.11/_sources/eks.md.txt @@ -0,0 +1,129 @@ +# Deploying Scylla on EKS + +This guide is focused on deploying Scylla on EKS with improved performance. +Performance tricks used by the script won't work with different machine tiers. +It sets up the kubelets on EKS nodes to run with [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and uses [local sdd disks](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ssd-instance-store.html) in RAID0 for maximum performance. + +Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the [general guide](generic.md). + +## TL;DR; + +If you don't want to run the commands step-by-step, you can just run a script that will set everything up for you: +```bash +# Edit according to your preference +EKS_REGION=us-east-1 +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c + +# From inside the examples/eks folder +cd examples/eks +./eks.sh -z "$EKS_ZONES" -r "$EKS_REGION" +``` + +After you deploy, see how you can [benchmark your cluster with cassandra-stress](generic.md#benchmark-with-cassandra-stress). + +## Walkthrough + +### EKS Setup + +#### Configure environment variables + +First of all, we export all the configuration options as environment variables. +Edit according to your own environment. + +``` +EKS_REGION=us-east-1 +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c +CLUSTER_NAME=scylla-demo +``` + +#### Creating an EKS cluster + +For this guide, we'll create an EKS cluster with the following: + +* A NodeGroup of 3 `i3-2xlarge` Nodes, where the Scylla Pods will be deployed. These nodes will only accept pods having `scylla-clusters` toleration. + +``` + - name: scylla-pool + instanceType: i3.2xlarge + desiredCapacity: 3 + labels: + scylla.scylladb.com/node-type: scylla + taints: + role: "scylla-clusters:NoSchedule" + ssh: + allow: true + kubeletExtraConfig: + cpuManagerPolicy: static +``` + +* A NodeGroup of 4 `c4.2xlarge` Nodes to deploy `cassandra-stress` later on. These nodes will only accept pods having `cassandra-stress` toleration. + +``` + - name: cassandra-stress-pool + instanceType: c4.2xlarge + desiredCapacity: 4 + labels: + pool: "cassandra-stress-pool" + taints: + role: "cassandra-stress:NoSchedule" + ssh: + allow: true +``` + +* A NodeGroup of 1 `i3.large` Node, where the monitoring stack and operator will be deployed. +``` + - name: monitoring-pool + instanceType: i3.large + desiredCapacity: 1 + labels: + pool: "monitoring-pool" + ssh: + allow: true +``` + +### Prerequisites + +#### Installing script third party dependencies + +Script requires several dependencies: +- eksctl - See: https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html +- kubectl - See: https://kubernetes.io/docs/tasks/tools/install-kubectl/ + +### Deploying ScyllaDB Operator + +Refer to [Deploying Scylla on a Kubernetes Cluster](generic.md) in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites. + +#### Setting up nodes for ScyllaDB + +ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you'll first need to form a RAID array from those disks. +`NodeConfig` performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in [Performance tuning](performance.md) section of ScyllaDB Operator's documentation. + +Deploy `NodeConfig` to let it take care of the above operations: +``` +kubectl apply --server-side -f examples/eks/nodeconfig-alpha.yaml +``` + +#### Deploying Local Volume Provisioner + +Afterwards, deploy ScyllaDB's [Local Volume Provisioner](https://github.com/scylladb/k8s-local-volume-provisioner), capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays. +``` +kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/ +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml +``` + +### Deploying ScyllaDB + +Now you can follow the steps described in [Deploying Scylla on a Kubernetes Cluster](generic.md) to launch your ScyllaDB cluster in a highly performant environment. + +#### Accessing the database + +Instructions on how to access the database can also be found in the [generic guide](generic.md). + +### Deleting an EKS cluster + +Once you are done with your experiments delete your cluster using the following command: + +``` +eksctl delete cluster "${CLUSTER_NAME}" +``` diff --git a/v1.11/_sources/exposing.md.txt b/v1.11/_sources/exposing.md.txt new file mode 100644 index 00000000000..348bc4c233d --- /dev/null +++ b/v1.11/_sources/exposing.md.txt @@ -0,0 +1,300 @@ +# Exposing ScyllaCluster + +This document explains how ScyllaDB Operator exposes ScyllaClusters in different network setups. +A ScyllaCluster can be exposed in various network configurations, independently to clients and nodes. + +:::{note} +ScyllaClusters can be only exposed when the ScyllaDB version used version is `>=2023.1` ScyllaDB Enterprise or `>=5.2` ScyllaDB Open Source. +::: + +## Expose Options + +`exposeOptions` specifies configuration options for exposing ScyllaCluster's. +A ScyllaCluster created without any `exposeOptions` is equivalent to the following: + +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: ClusterIP + broadcastOptions: + clients: + type: ServiceClusterIP + nodes: + type: ServiceClusterIP +``` + +The following sections cover what every field controls and what the configuration options are. + +### Node Service Template + +`nodeService` serves as a template for a node-dedicated Service managed by the Scylla Operator for each node within a ScyllaCluster. +The properties of the Services depend on the selected type. +Additionally, there's an option to define custom annotations, incorporated into each node's Service, +which might be useful for further tweaking the Service properties or related objects. + +#### Headless Type + +For `Headless` type, Scylla Operator creates a Headless Service with a selector pointing to the particular node in the ScyllaCluster. +Such Service doesn't provide any additional IP addresses, and the internal DNS record resolves to the PodIP of a node. + +This type of Service is useful when ScyllaCluster nodes broadcast PodIPs to clients and other nodes. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: Headless +``` + +#### ClusterIP Type + +For `ClusterIP` type, Scylla Operator creates a ClusterIP Service backed by a specific node in the ScyllaCluster. + +These IP addresses are only routable within the same Kubernetes cluster, so it's a good fit, if you don't want to expose them to other networks. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: ClusterIP +``` + +#### LoadBalancer Type + +For the `LoadBalancer` type, Scylla Operator generates a LoadBalancer Service that directs traffic to a specific node within the ScyllaCluster. +On platforms with support for external load balancers, this Service provisions one. +The accessibility of this load balancer's address depends on the platform and any customizations made; in some cases it may be reachable from the internal network or public Internet. + +Customizations are usually managed via Service annotations, key-value pairs provided in `annotations` field are merged into each Service object. +LoadBalancer Services should be configured to pass through entire traffic. +For example, to expose LoadBalancer only to internal network use the following annotations: + +::::{tab-set} +:::{tab-item} EKS +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: LoadBalancer + annotations: + service.beta.kubernetes.io/aws-load-balancer-scheme: internal + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp +``` +::: +:::{tab-item} GKE +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: LoadBalancer + annotations: + networking.gke.io/load-balancer-type: Internal +``` +::: +:::: + +Check platform-specific documentation regarding LoadBalancer configuration to learn more about available options. + +LoadBalancer Service is a superset of ClusterIP Service, implying that each LoadBalancer Service also contains an allocated ClusterIP. +They can be configured using the following fields, which propagate to every node Service: +* externalTrafficPolicy +* internalTrafficPolicy +* loadBalancerClass +* allocateLoadBalancerNodePorts + +Check [Kubernetes Service documentation](https://kubernetes.io/docs/concepts/services-networking/service) to learn more about these options. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: LoadBalancer + loadBalancerClass: my-custom-load-balancer-class +``` + +--- + +### Broadcast Options + +Broadcast options control what is the source of the address being broadcasted to clients and nodes. +It's configured independently for clients and nodes because you may want to expose these two types of traffic on different networks. +Using different networks can help manage costs, reliability, latency, security policies or other metrics you care about. + +#### PodIP Type + +Address broadcasted to clients/nodes is taken from Pod. +By default, the address is taken from Pod's `status.PodIP` field. +Because a Pod can use multiple address, you may want to provide source options by specifying `podIP.source`. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + broadcastOptions: + clients: + type: PodIP + podIP: + source: Status +``` + +#### ServiceClusterIP Type + +Address broadcasted to clients or nodes is taken from `spec.ClusterIP` field of a node's dedicated Service. + +In order to configure it, the `nodeService` template must specify a Service having a ClusterIP assigned. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + broadcastOptions: + clients: + type: ServiceClusterIP +``` + +#### ServiceLoadBalancerIngress Type + +Address broadcasted to clients/nodes is taken from the node dedicated Service, from `status.ingress[0].ipAddress` or `status.ingress[0].hostname` field. + +In order to configure it, the `nodeService` template must specify the LoadBalancer Service. + +Example: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + broadcastOptions: + clients: + type: ServiceLoadBalancerIngress + podIP: + source: Status +``` + +## Deployment Examples + +The following section contains several specific examples of various network scenarios and explains how nodes and clients communicate with one another. +### In-cluster only + +ScyllaCluster definition: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: ClusterIP + broadcastOptions: + clients: + type: ServiceClusterIP + nodes: + type: ServiceClusterIP +``` + +Both client and nodes are deployed within the same Kubernetes cluster. +They talk through ClusterIP addresses taken from the Service. +Because ClusterIP Services are only routable within the same Kubernetes cluster, this cluster won't be reachable from outside. + +![ClusterIPs](static/exposing/clusterip.svg) + +### In-cluster node-to-node, VPC clients-to-nodes + +ScyllaCluster definition: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: ClusterIP + broadcastOptions: + clients: + type: PodIP + nodes: + type: ServiceClusterIP +``` + +In this scenario, we assume that the Pod IP subnet is routable within a VPC. +Clients within the VPC network can communicate directly with ScyllaCluster nodes using PodIPs. +Nodes communicate with each other exclusively within the same Kubernetes cluster. + +![PodIPs](static/exposing/podips.svg) + +### Multi VPC + +ScyllaCluster definition: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: Headless + broadcastOptions: + clients: + type: PodIP + nodes: + type: PodIP +``` + +In this scenario, we set up two separate Kubernetes clusters in distinct VPCs. +These VPCs are interconnected to facilitate inter-VPC connectivity. +We operate on the assumption that the Pod IP subnet is routable within each VPC. + +Both ScyllaClusters use the same `exposeOptions`, nodes broadcast their Pod IP addresses, enabling them to establish connections with one another. +****Check other documentation pages to know how to connect two ScyllaClusters into one logical cluster. + +Clients, whether deployed within the same Kubernetes cluster or within a VPC, have the capability to reach nodes using their Pod IPs. +Since there is no requirement for any address other than the Pod IP, the `Headless` service type is sufficient. + +![MultiVPC](static/exposing/multivpc.svg) + +### Internet + +ScyllaCluster definition: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: LoadBalancer + broadcastOptions: + clients: + type: ServiceLoadBalancerIngress + nodes: + type: ClusterIP +``` + +We assume that a Kubernetes cluster has been deployed in a cloud provider environment that supports external load balancers. +By specifying the LoadBalancer type in the nodeService template, the Scylla Operator generates a dedicated LB Service for each node. +The cloud provider then establishes an external load balancer with an internet-accessible address. +ScyllaDB nodes broadcast this external address to clients, enabling drivers to connect and discover other nodes. +Since all ScyllaDB nodes reside within the same Kubernetes cluster, there is no need to route traffic through the internet. +Consequently, the nodes are configured to communicate via ClusterIP, which is also accessible within LoadBalancer Services. + +![Internet](static/exposing/loadbalancer.svg) + +--- + +Other more complex scenarios can be built upon these simple ones. diff --git a/v1.11/_sources/generic.md.txt b/v1.11/_sources/generic.md.txt new file mode 100644 index 00000000000..d2b26fd16fd --- /dev/null +++ b/v1.11/_sources/generic.md.txt @@ -0,0 +1,386 @@ +# Deploying Scylla on a Kubernetes Cluster + +This is a guide to deploy a Scylla Cluster in a generic Kubernetes environment, meaning that Scylla will not be deployed with the ideal performance. +Scylla performs the best when it has fast disks and direct access to the cpu. +This requires some extra setup, which is platform-specific. +For specific configuration and setup, check for details about your particular environment: + +* [GKE](gke.md) + +## Prerequisites + +* A Kubernetes cluster +* A [Storage Class](https://kubernetes.io/docs/concepts/storage/storage-classes/) to provision [PersistentVolumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/). +* Helm 3 installed, Go to the [helm docs](https://docs.helm.sh/using_helm/#installing-helm) if you need to install it. + Make sure that you enable the [stable repository](https://github.com/helm/charts#how-do-i-enable-the-stable-repository-for-helm-3) + +## Running locally + +Running kubernetes locally is a daunting and error prone task. +Fortunately there are ways to make life easier and [Minikube](https://minikube.sigs.k8s.io/docs/) makes it a breeze. + +We need to give minikube a little bit more resources than default so start minikube like this: +```console +minikube start --cpus=6 +``` + +Then make kubectl aware of this local installation like this: +```console +eval $(minikube docker-env) +``` + +## Download Scylla Operator +In this guide you will be using the examples and manifests from [Scylla Operator repository](https://github.com/scylladb/scylla-operator), so start off by cloning it to your local machine. +```console +git clone git@github.com:scylladb/scylla-operator.git +cd scylla-operator +``` + +## Deploy Cert Manager +First deploy Cert Manager, you can either follow [upsteam instructions](https://cert-manager.io/docs/installation/kubernetes/) or use following command: + +```console +kubectl apply -f examples/common/cert-manager.yaml +``` +This will install Cert Manager to provision a self-signed certificate. + +Once it's deployed, wait until Cert Manager is ready: + +```console +kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io +kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook +``` + +## Deploy Scylla Operator + +Deploy the Scylla Operator using the following commands: + +```console +kubectl apply -f examples/common/operator.yaml +``` + +This will install the operator in namespace `scylla-operator`. +Wait until it's ready: + +```console +kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator +``` + +If you want to check the logs of the operator you can do so with: + + ```console +kubectl -n scylla-operator logs deployment.apps/scylla-operator +``` + +## Create and Initialize a Scylla Cluster + +Now that the operator is running, we can create an instance of a Scylla cluster by creating an instance of the `clusters.scylla.scylladb.com` resource. +Some of that resource's values are configurable, so feel free to browse `cluster.yaml` and tweak the settings to your liking. +Full details for all the configuration options can be found in the [Scylla Cluster CRD documentation](scylla-cluster-crd.md). + +When you are ready to create a Scylla cluster, simply run: + +```console +kubectl create -f examples/generic/cluster.yaml +``` + +We can verify that a Kubernetes object has been created that represents our new Scylla cluster with the command below. +This is important because it shows that has successfully extended Kubernetes to make Scylla clusters a first class citizen in the Kubernetes cloud-native environment. + +```console +kubectl -n scylla get ScyllaCluster +``` + +Checking the pods that are created is as easy as: + +```console +kubectl -n scylla get pods +``` + +The output should be something like: + +```console +NAME READY STATUS RESTARTS AGE +simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 9m49s +simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 7m43s +simple-cluster-us-east-1-us-east-1a-2 2/2 Running 0 6m46s +``` + +It is important to note that the operator creates these instances according to a pattern. +This pattern is as follows: `CLUSTER_NAME-DATACENTER_NAME-RACK_NAME-INSTANCE_NUMBER` as specified in `cluster.yaml`. + +In the above example we have the following properties: + + - CLUSTER_NAME: `simple-cluster` + - DATACENTER_NAME: `us-east-1` + - RACK_NAME: `us-east-1a` + - INSTANCE_NUMBER: An automatically generated number attached to the pod name. + +We picked the names to resemble something you can find in a cloud service but this is inconsequential, they can be set to anything you want. + +To check if all the desired members are running, you should see the same number of entries from the following command as the number of members that was specified in `cluster.yaml`: + +```console +kubectl -n scylla get pod -l app=scylla +``` + +You can also track the state of a Scylla cluster from its status. To check the current status of a Cluster, run: + +```console +kubectl -n scylla describe ScyllaCluster simple-cluster +``` + +Checking the logs of the running scylla instances can be done like this: + +```console +kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 scylla +``` + +### Configure host networking + +To squeeze the most out of your deployment it is sometimes necessary to employ [host networking](https://kubernetes.io/docs/concepts/services-networking/). +To enable this the CRD allows for specifying a `network` parameter as such: + +```yaml +version: 4.0.0 + agentVersion: 2.0.2 + cpuset: true + network: + hostNetworking: true +``` + +This will result in hosts network to be used for the Scylla Stateful Set deployment. + +### Configure container kernel parameters + +Sometimes it is necessary to run the container with different kernel parameters. +In order to support this, the Scylla Operator defines a cluster property `sysctls` that is a list of the desired key-value pairs to set. + +___For example___: To increase the number events available for asynchronous IO processing in the Linux kernel to N set sysctls to`fs.aio-max-nr=N`. + +```yaml +spec: + sysctls: + - "fs.aio-max-nr=2097152" +``` + +### Deploying Alternator + +The operator is also capable of deploying [Alternator](https://www.scylladb.com/alternator/) instead of the regular Scylla. +This requires a small change in the cluster definition. +Change the `cluster.yaml` file from this: +```yaml +spec: + version: 4.0.0 + agentVersion: 2.0.2 + developerMode: true + datacenter: + name: us-east-1 +``` +to this: +```yaml +spec: + version: 4.0.0 + alternator: + port: 8000 + writeIsolation: only_rmw_uses_lwt + agentVersion: 2.0.2 + developerMode: true + datacenter: + name: us-east-1 +``` +You can specify whichever port you want. + +You must provide desired write isolation, supported values are: "always", "forbid_rmw", "only_rmw_uses_lwt". +Difference between those isolation levels can be found in Scylla Alternator documentation. + +Once this is done the regular CQL ports will no longer be available, the cluster is a pure Alternator cluster. + +## Accessing the Database + +* From kubectl: + +To get a cqlsh shell in your new Cluster: +```console +kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- cqlsh +> DESCRIBE KEYSPACES; +``` + + +* From inside a Pod: + +When you create a new Cluster, automatically creates a Service for the clients to use in order to access the Cluster. +The service's name follows the convention `-client`. +You can see this Service in your cluster by running: +```console +kubectl -n scylla describe service simple-cluster-client +``` +Pods running inside the Kubernetes cluster can use this Service to connect to Scylla. +Here's an example using the [Python Driver](https://github.com/datastax/python-driver): +```python +from cassandra.cluster import Cluster + +cluster = Cluster(['simple-cluster-client.scylla.svc']) +session = cluster.connect() +``` + +If you are running the Alternator you can access the API on the port you specified using plain http. + +## Configure Scylla + +The operator can take a ConfigMap and apply it to the scylla.yaml configuration file. +This is done by adding a ConfigMap to Kubernetes and refering to this in the Rack specification. +The ConfigMap is just a file called `scylla.yaml` that has the properties you want to change in it. +The operator will take the default properties for the rest of the configuration. + +* Create a ConfigMap the default name that the operator uses is `scylla-config`: +```console +kubectl create configmap scylla-config -n scylla --from-file=/path/to/scylla.yaml +``` +* Wait for the mount to propagate and then restart the cluster: +```console +kubectl rollout restart -n scylla statefulset/simple-cluster-us-east-1-us-east-1a +``` +* The new config should be applied automatically by the operator, check the logs to be sure. + +Configuring `cassandra-rackdc.properties` is done by adding the file to the same mount as `scylla.yaml`. +```console +kubectl create configmap scylla-config -n scylla --from-file=/tmp/scylla.yaml --from-file=/tmp/cassandra-rackdc.properties -o yaml --dry-run | kubectl replace -f - +``` +The operator will then apply the overridable properties `prefer_local` and `dc_suffix` if they are available in the provided mounted file. + +:::{note} +If you want to enable authentication, you first need to adjust `system_auth` keyspace replication factor to the number of nodes in the datacenter via cqlsh. It allows you to ensure that the user’s information is kept highly available for the cluster. If `system_auth` is not equal to the number of nodes and a node fails, the user whose information is on that node will be denied access. +For production environments only use `NetworkTopologyStrategy`. + +```shell +kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : };" +``` + +You can read more about enabling authentication in the [Enable authentication](https://opensource.docs.scylladb.com/stable/operating-scylla/security/authentication.html) section of ScyllaDB's documentation. +::: + +## Configure Scylla Manager Agent + +The operator creates a second container for each scylla instance that runs [Scylla Manager Agent](https://hub.docker.com/r/scylladb/scylla-manager-agent). +This container serves as a sidecar and it's the main endpoint for interacting with Scylla API. +The Scylla Manager Agent can be configured with various things such as the security token used to allow access to Scylla API and storage providers for backups. + +To configure the agent you just create a new secret called _scylla-agent-config-secret_ and populate it with the contents in the `scylla-manager-agent.yaml` file like this: +```console +kubectl create secret -n scylla generic scylla-agent-config-secret --from-file scylla-manager-agent.yaml +``` + +See [Scylla Manager Agent configuration](https://manager.docs.scylladb.com/stable/config/scylla-manager-config.html) for a complete reference of the Scylla Manager agent config file. + +### Scylla Manager Agent auth token + +Operator provisions Agent auth token by copying value from user provided config secret or auto generates it if it's empty. +To check which value is being used, decode content of `-auth-token` secret. +To change it simply remove the secret. Operator will create a new one. To pick up the change in the cluster, initiate a rolling restart. + +## Set up monitoring + +To set up monitoring using Prometheus and Grafana follow [this guide](monitoring.md). + +## Scale a ScyllaCluster + +The operator supports adding new nodes to existing racks, adding new racks to the cluster, as well as removing both single nodes and entire racks. To introduce the changes, edit the cluster with: +```console +kubectl -n scylla edit scyllaclusters.scylla.scylladb.com/simple-cluster +``` +* To modify the number of nodes in a rack, update the `members` field of the selected rack to a desired value. +* To add a new rack, append it to the `.spec.datacenter.racks` list. Remember to choose a unique rack name for the new rack. +* To remove a rack, first scale it down to zero nodes, and then remove it from `.spec.datacenter.racks` list. + +Having edited and saved the yaml, you can check your cluster's Status and Events to retrieve information about what's happening: +```console +kubectl -n scylla describe scyllaclusters.scylla.scylladb.com/simple-cluster +``` + +:::{note} +If you have configured ScyllaDB with `authenticator` set to `PasswordAuthenticator`, you need to manually configure the replication factor of the `system_auth` keyspace with every scaling operation. + +```shell +kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -u -p -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : };" +``` + +It is recommended to set `system_auth` replication factor to the number of nodes in each datacenter. +::: + +## Benchmark with cassandra-stress + +After deploying our cluster along with the monitoring, we can benchmark it using cassandra-stress and see its performance in Grafana. We have a mini cli that generates Kubernetes Jobs that run cassandra-stress against a cluster. + +> Because cassandra-stress doesn't scale well to multiple cores, we use multiple jobs with a small core count for each + +```bash + +# Run a benchmark with 10 jobs, with 6 cpus and 50.000.000 operations each. +# Each Job will throttle throughput to 30.000 ops/sec for a total of 300.000 ops/sec. +hack/cass-stress-gen.py --num-jobs=10 --cpu=6 --memory=20G --ops=50000000 --limit=30000 +kubectl apply -f scripts/cassandra-stress.yaml +``` + +Make sure you set the proper arguments in case you have altered things such as _name_ or _namespace_. + +```bash +./hack/cass-stress-gen.py -h +usage: cass-stress-gen.py [-h] [--num-jobs NUM_JOBS] [--name NAME] [--namespace NAMESPACE] [--scylla-version SCYLLA_VERSION] [--host HOST] [--cpu CPU] [--memory MEMORY] [--ops OPS] [--threads THREADS] [--limit LIMIT] + [--connections-per-host CONNECTIONS_PER_HOST] [--print-to-stdout] [--nodeselector NODESELECTOR] + +Generate cassandra-stress job templates for Kubernetes. + +optional arguments: + -h, --help show this help message and exit + --num-jobs NUM_JOBS number of Kubernetes jobs to generate - defaults to 1 + --name NAME name of the generated yaml file - defaults to cassandra-stress + --namespace NAMESPACE + namespace of the cassandra-stress jobs - defaults to "default" + --scylla-version SCYLLA_VERSION + version of scylla server to use for cassandra-stress - defaults to 4.0.0 + --host HOST ip or dns name of host to connect to - defaults to scylla-cluster-client.scylla.svc + --cpu CPU number of cpus that will be used for each job - defaults to 1 + --memory MEMORY memory that will be used for each job in GB, ie 2G - defaults to 2G * cpu + --ops OPS number of operations for each job - defaults to 10000000 + --threads THREADS number of threads used for each job - defaults to 50 * cpu + --limit LIMIT rate limit for each job - defaults to no rate-limiting + --connections-per-host CONNECTIONS_PER_HOST + number of connections per host - defaults to number of cpus + --print-to-stdout print to stdout instead of writing to a file + --nodeselector NODESELECTOR + nodeselector limits cassandra-stress pods to certain nodes. Use as a label selector, eg. --nodeselector role=scylla +``` +While the benchmark is running, open up Grafana and take a look at the monitoring metrics. + +After the Jobs finish, clean them up with: +```bash +kubectl delete -f scripts/cassandra-stress.yaml +``` + +## Clean Up + +To clean up all resources associated with this walk-through, you can run the commands below. + +**NOTE:** this will destroy your database and delete all of its associated data. + +```console +kubectl delete -f examples/generic/cluster.yaml +kubectl delete -f examples/common/operator.yaml +kubectl delete -f examples/common/cert-manager.yaml +``` + +## Troubleshooting + +If the cluster does not come up, the first step would be to examine the operator's logs: + +```console +kubectl -n scylla-operator logs deployment.apps/scylla-operator +``` + +If everything looks OK in the operator logs, you can also look in the logs for one of the Scylla instances: + +```console +kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 +``` diff --git a/v1.11/_sources/gke.md.txt b/v1.11/_sources/gke.md.txt new file mode 100644 index 00000000000..cfad6709a17 --- /dev/null +++ b/v1.11/_sources/gke.md.txt @@ -0,0 +1,173 @@ +# Deploying Scylla on GKE + +This guide is focused on deploying Scylla on GKE with maximum performance (without any persistence guarantees). +It sets up the kubelets on GKE nodes to run with [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and uses [local sdd disks](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/local-ssd) in RAID0 for maximum performance. + +Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the [general guide](generic.md). + +## TL;DR; + +If you don't want to run the commands step-by-step, you can just run a script that will set everything up for you: +```bash +# Edit according to your preference +GCP_USER=$(gcloud config list account --format "value(core.account)") +GCP_PROJECT=$(gcloud config list project --format "value(core.project)") +GCP_ZONE=us-west1-b + +# From inside the examples/gke folder +cd examples/gke +./gke.sh -u "$GCP_USER" -p "$GCP_PROJECT" -z "$GCP_ZONE" + +# Example: +# ./gke.sh -u yanniszark@arrikto.com -p gke-demo-226716 -z us-west1-b +``` + +:::{warning} +Make sure to pass a ZONE (ex.: us-west1-b) and not a REGION (ex.: us-west1) or it will deploy nodes in each ZONE available in the region. +::: + +After you deploy, see how you can [benchmark your cluster with cassandra-stress](generic.md#benchmark-with-cassandra-stress). + +## Walkthrough + +### Google Kubernetes Engine Setup + +#### Configure environment variables + +First of all, we export all the configuration options as environment variables. +Edit according to your own environment. + +``` +GCP_USER=$( gcloud config list account --format "value(core.account)" ) +GCP_PROJECT=$( gcloud config list project --format "value(core.project)" ) +GCP_REGION=us-west1 +GCP_ZONE=us-west1-b +CLUSTER_NAME=scylla-demo +CLUSTER_VERSION=$( gcloud container get-server-config --zone ${GCP_ZONE} --format "value(validMasterVersions[0])" ) +``` + +#### Creating a GKE cluster + +First we need to change kubelet CPU Manager policy to static by providing a config file. Create file called `systemconfig.yaml` with the following content: +``` +kubeletConfig: + cpuManagerPolicy: static +``` + +Then we'll create a GKE cluster with the following: + +1. A NodePool of 2 `n1-standard-8` Nodes, where the operator and the monitoring stack will be deployed. These are generic Nodes and their free capacity can be used for other purposes. + ``` + gcloud container \ + clusters create "${CLUSTER_NAME}" \ + --cluster-version "${CLUSTER_VERSION}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-8" \ + --num-nodes "2" \ + --disk-type "pd-ssd" --disk-size "20" \ + --image-type "UBUNTU_CONTAINERD" \ + --system-config-from-file=systemconfig.yaml \ + --enable-stackdriver-kubernetes \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +2. A NodePool of 2 `n1-standard-32` Nodes to deploy `cassandra-stress` later on. + + ``` + gcloud container --project "${GCP_PROJECT}" \ + node-pools create "cassandra-stress-pool" \ + --cluster "${CLUSTER_NAME}" \ + --zone "${GCP_ZONE}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-32" \ + --num-nodes "2" \ + --disk-type "pd-ssd" --disk-size "20" \ + --node-taints role=cassandra-stress:NoSchedule \ + --image-type "UBUNTU_CONTAINERD" \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +3. A NodePool of 4 `n1-standard-32` Nodes, where the Scylla Pods will be deployed. Each of these Nodes has 8 local NVMe SSDs attached, which are provided as [raw block devices](https://cloud.google.com/kubernetes-engine/docs/concepts/local-ssd#block). It is important to disable `autoupgrade` and `autorepair`. Automatic cluster upgrade or node repair has a hard timeout after which it no longer respect PDBs and force deletes the Compute Engine instances, which also deletes all data on the local SSDs. At this point, it's better to handle upgrades manually, with more control over the process and error handling. + ``` + gcloud container \ + node-pools create "scylla-pool" \ + --cluster "${CLUSTER_NAME}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-32" \ + --num-nodes "4" \ + --disk-type "pd-ssd" --disk-size "20" \ + --local-nvme-ssd-block count="8" \ + --node-taints role=scylla-clusters:NoSchedule \ + --node-labels scylla.scylladb.com/node-type=scylla \ + --image-type "UBUNTU_CONTAINERD" \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +#### Setting Yourself as `cluster-admin` +> (By default GKE doesn't give you the necessary RBAC permissions) + +Get the credentials for your new cluster +``` +gcloud container clusters get-credentials "${CLUSTER_NAME}" --zone="${GCP_ZONE}" +``` + +Create a ClusterRoleBinding for your user. +In order for this to work you need to have at least permission `container.clusterRoleBindings.create`. +The easiest way to obtain this permission is to enable the `Kubernetes Engine Admin` role for your user in the GCP IAM web interface. +``` +kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user "${GCP_USER}" +``` + + +### Prerequisites + +### Deploying ScyllaDB Operator + +Refer to [Deploying Scylla on a Kubernetes Cluster](generic.md) in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites. + +#### Setting up nodes for ScyllaDB + +ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you'll first need to form a RAID array from those disks. +`NodeConfig` performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in [Performance tuning](performance.md) section of ScyllaDB Operator's documentation. + +Deploy `NodeConfig` to let it take care of the above operations: +``` +kubectl apply --server-side -f examples/gke/nodeconfig-alpha.yaml +``` + +#### Deploying Local Volume Provisioner + +Afterwards, deploy ScyllaDB's [Local Volume Provisioner](https://github.com/scylladb/k8s-local-volume-provisioner), capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays. +``` +kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/ +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml +``` + +### Deploy Scylla cluster +In order for the example to work you need to modify the cluster definition in the following way: + +``` +sed -i "s//${GCP_REGION}/g;s//${GCP_ZONE}/g" examples/gke/cluster.yaml +``` + +This will inject your region and zone into the cluster definition so that it matches the kubernetes cluster you just created. + +### Deploying ScyllaDB + +Now you can follow the steps described in [Deploying Scylla on a Kubernetes Cluster](generic.md) to launch your ScyllaDB cluster in a highly performant environment. + +#### Accessing the database + +Instructions on how to access the database can also be found in the [generic guide](generic.md). + +### Deleting a GKE cluster + +Once you are done with your experiments delete your cluster using the following command: + +``` +gcloud container --project "${GCP_PROJECT}" clusters delete --zone "${GCP_ZONE}" "${CLUSTER_NAME}" +``` diff --git a/v1.11/_sources/helm.md.txt b/v1.11/_sources/helm.md.txt new file mode 100644 index 00000000000..56fbe9620ac --- /dev/null +++ b/v1.11/_sources/helm.md.txt @@ -0,0 +1,339 @@ +# Deploying Scylla stack using Helm Charts + +In this example we will install Scylla stack on Kubernetes. This includes the following components: +- Scylla Operator +- Scylla Manager +- Scylla + +We will use Minikube K8s cluster, but this could be any K8s cluster supported by the Scylla Operator. + +### Prerequisites + +- Kubernetes 1.16+ +- Helm 3+ + +### TL;DR + +``` +helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable +helm repo update +kubectl apply -f examples/common/cert-manager.yaml +helm install scylla-operator scylla/scylla-operator --create-namespace --namespace scylla-operator +helm install scylla-manager scylla/scylla-manager --create-namespace --namespace scylla-manager +helm install scylla scylla/scylla --create-namespace --namespace scylla +``` + +### Deploy Cert Manager + +This step is optional if you want to use your own certificate. +If you don't have one, make sure to not disable autogeneration using Scylla Operator Helm Chart. + +First deploy Cert Manager, you can either follow [upsteam instructions](https://cert-manager.io/docs/installation/kubernetes/) or use following command: + +```console +kubectl apply -f examples/common/cert-manager.yaml +``` + +Once it's deployed, wait until all Cert Manager pods will enter into Running state: + +```console +kubectl wait -n cert-manager --for=condition=ready pod -l app=cert-manager --timeout=60s +``` + +### Helm Chart repository + +To install Scylla Helm Chart repository execute the following commands: +``` +helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable +helm repo update +``` + +Then you can search through repository, it should contain at least three Helm charts: +``` +helm search repo scylla +NAME CHART VERSION APP VERSION DESCRIPTION +scylla/scylla 1.0.1 v1.0.1 Scylla is a close-to-the-hardware rewrite of Ca... +scylla/scylla-manager 1.0.1 v1.0.1 Scylla Manager automates database operations. +scylla/scylla-operator 1.0.1 v1.0.1 Scylla Operator is a Kubernetes Operator for ma... +``` + +All these charts should be installable without any need of customizing (defaults are provided). +Although Helm is used for this particular reason, so lets customize them a bit. + +### Scylla Operator Chart + +This chart is very simple, most interesting customizable fields are `image`, `resources` and `webhook`. +All others can be looked up in Chart source in Scylla Operator repository. + +#### image + +Image allows to define which Scylla Operator image will be used. By default it downloads the image from main +Docker Hub repository, using version defined in Helm Chart. +You can also change `pullPolicy` if default one does not +fullfill your needs. In [Kubernetes documentation](https://kubernetes.io/docs/concepts/containers/images/) you +can read more about different pull policies. + +Image URL will be composed based on these fields in follwing pattern: +`repository/scylla-operator:tag` +```yaml +image: + repository: scylladb + pullPolicy: IfNotPresent + tag: "" +``` + +#### resources + +You can customize how much resources will be allocated for Operator pods via `resource` field: +```yaml +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 32Mi +``` + +To read more about resource specification, follow [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +#### webhook + +Webhook field allows to decide whether you want to use autogenerated self-signed certificate using Cert Manager or +whether you want to provide your own certificate. + +`createSelfSignedCertificate` specifies whether a self-signed certificate should be created using Cert Manager +`certificateSecretName`: name of a secret containing custom certificate. + +```yaml +webhook: + createSelfSignedCertificate: true + certificateSecretName: "" +``` + +#### Customization + +You can customize all these fields and others by providing file containing desired values. +Content of this file will overwrite default values. + +You can find an example in Scylla Operator repository under `examples/helm/values.operator.yaml` + +#### Installation + +To deploy Scylla Operator using customized values file execute the following: +``` +helm install scylla-operator scylla/scylla-operator --values examples/helm/values.operator.yaml --create-namespace --namespace scylla-operator +``` + +### Scylla Helm Chart + +Scylla Chart allows to customize and deploy Scylla cluster. +By default Scylla Helm charts deploys working Scylla cluster, but of course we can customize it. + +#### Customization + +Versions of images used in the cluster can be set via `scyllaImage` and `agentImage` +```yaml +scyllaImage: + repository: scylladb/scylla + tag: 4.3.0 + +agentImage: + repository: scylladb/scylla-manager-agent + tag: 2.2.1 +``` + +A minimal Scylla cluster can be expressed as: +```yaml +datacenter: us-east-1 +racks: +- name: us-east-1b + members: 2 + storage: + capacity: 5G + resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 1 + memory: 1Gi +``` + +Above cluster will use 4.3.0 Scylla, 2.2.1 Scylla Manager Agent sidecar and will have a single rack having 2 nodes. +Each node will have a single CPU and 1 GiB of memory. + +For other customizable fields, please refer to [ScyllaCluster CRD definition](scylla-cluster-crd.md). +CRD Rack Spec and Helm Chart Rack should have the same fields. + +#### Installation + +To deploy Scylla cluster using customzied values file execute the following command: +``` +helm install scylla scylla/scylla --values examples/helm/values.cluster.yaml --create-namespace --namespace scylla +``` + +Scylla Operator will provision this cluster on your K8s environment. + +### Scylla Manager Helm Chart + +Scylla Manager Chart allows to customize and deploy Scylla Manager in K8s environment. +Scylla Manager consist of two applications (Scylla Manager itself and Scylla Manager Controller) and additional Scylla cluster. + +To read more about Scylla Manager see [Manager guide](manager.md). + +#### Scylla Manager + +To set version of used Scylla Manager you can use `image` field: +```yaml +image: + repository: scylladb + pullPolicy: IfNotPresent + tag: 2.2.1 +``` +To control how many resources are allocated for Scylla Manager use `resource` field: +```yaml +resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 500m + memory: 500Mi +``` + +#### Scylla Manager Controller + +Similarly Scylla Manager Controller image can be customized: + +```yaml +controllerImage: + repository: scylladb + pullPolicy: IfNotPresent + tag: "" +``` + +And allocated resources: +```yaml +controllerResources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi +``` + +#### Scylla + +To customize internal Scylla instance dedicated to Scylla Manager, see guide above customizing Scylla Helm Chart. +It's definition should land as a `scylla` field. + +#### Customization + +All others customizable fields can be looked up in Chart source in Scylla Operator repository. + +#### Installation + +To deploy Scylla Manager using customized values file execute the following command: +``` +helm install scylla-manager scylla/scylla-manager --values examples/helm/values.manager.yaml --create-namespace --namespace scylla-manager +``` + +## Results + +Scylla need some time to bootstrap all nodes, but after some time you should be ready to roll. It was simple isn't it? +You can validate if everything was set up correctly by looking at the all resources created in used namespaces. + +Scylla Operator: +```shell +$ kubectl -n scylla-operator get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-operator-5dbcb54f5c-vjm4m 1/1 Running 0 51s +pod/scylla-operator-5dbcb54f5c-wfjbw 1/1 Running 0 51s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-operator-webhook ClusterIP 10.105.207.130 443/TCP 51s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/scylla-operator 2/2 2 2 51s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/scylla-operator-5dbcb54f5c 2 2 2 51s + +``` + +Operator is running! + +Scylla Manager: +```shell +$ kubectl -n scylla-manager get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-manager-669db64dd-bcm4v 1/1 Running 0 89s +pod/scylla-manager-controller-844ccc56c4-drbth 1/1 Running 0 89s +pod/scylla-manager-controller-844ccc56c4-rhwqx 1/1 Running 0 89s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-manager ClusterIP 10.105.231.53 80/TCP,5090/TCP 89s +service/scylla-manager-client ClusterIP None 9180/TCP,5090/TCP 89s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/scylla-manager 1/1 1 1 89s +deployment.apps/scylla-manager-controller 2/2 2 2 89s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/scylla-manager-669db64dd 1 1 1 89s +replicaset.apps/scylla-manager-controller-844ccc56c4 2 2 2 89s + + +``` + +Good to go, ready to serve! + +Scylla itself: +```shell +$ kubectl -n scylla get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-us-east-1-us-east-1b-0 2/2 Running 0 5m58s +pod/scylla-us-east-1-us-east-1b-1 2/2 Running 0 4m29s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-client ClusterIP None 9180/TCP,5090/TCP 5m59s +service/scylla-us-east-1-us-east-1b-0 ClusterIP 10.43.149.92 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 5m58s +service/scylla-us-east-1-us-east-1b-1 ClusterIP 10.43.49.0 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 4m29s + +NAME READY AGE +statefulset.apps/scylla-us-east-1-us-east-1b 2/2 5m59s +``` + +Two running nodes, exactly what we were asking for. + +## Monitoring + +To spin up a Prometheus monitoring refer to [monitoring guide](monitoring.md). + +Helm charts can create ServiceMonitors needed to observe Scylla Managger and Scylla. +Both of these Helm Charts allows to specify whether you want to create a ServiceMonitor: +```yaml +serviceMonitor: + create: false +``` + +Change `create` to `true` and update your current deployment using: +```shell +helm upgrade --install scylla --namespace scylla scylla/scylla -f examples/helm/values.cluster.yaml +``` + +Helm should notice the difference, install the ServiceMonitor, and then Prometheous will be able to scrape metrics. + +## Cleanup + +To remove these applications you can simply uninstall them using Helm CLI: +```shell +helm uninstall scylla -n scylla +helm uninstall scylla-manager -n scylla-manager +helm uninstall scylla-operator -n scylla-operator +``` diff --git a/v1.11/_sources/index.rst.txt b/v1.11/_sources/index.rst.txt new file mode 100644 index 00000000000..7891296c2c1 --- /dev/null +++ b/v1.11/_sources/index.rst.txt @@ -0,0 +1,65 @@ +============================= +Scylla Operator Documentation +============================= + +.. toctree:: + :hidden: + :maxdepth: 1 + + generic + eks + gke + helm + manager + monitoring + migration + nodeoperations/index + exposing + multidc/index + performance + upgrade + releases + support/index + scylla-cluster-crd + contributing + +Scylla Operator is an open source project which helps users of Scylla Open Source and Scylla Enterprise run Scylla on Kubernetes (K8s) +The Scylla operator manages Scylla clusters deployed to Kubernetes and automates tasks related to operating a Scylla cluster, like installation, out and downscale, rolling upgrades. + +.. image:: logo.png + :width: 200pt + +For the latest status of the project, and reports issue, see the Github Project. Also check out the K8s Operator lesson on Scylla University. + +scylla-operator is a Kubernetes Operator for managing Scylla clusters. + +Currently it supports: + +* Deploying multi-zone clusters +* Scaling up or adding new racks +* Scaling down +* Monitoring with Prometheus and Grafana +* Integration with `Scylla Manager `_ +* Dead node replacement +* Version Upgrade +* Backup +* Repairs +* Autohealing + +**Choose a topic to begin**: + +* :doc:`Deploying Scylla on a Kubernetes Cluster ` +* :doc:`Deploying Scylla on EKS ` +* :doc:`Deploying Scylla on GKE ` +* :doc:`Deploying Scylla Manager on a Kubernetes Cluster ` +* :doc:`Deploying Scylla stack using Helm Charts ` +* :doc:`Setting up Monitoring using Prometheus and Grafana ` +* :doc:`Node operations ` +* :doc:`Exposing ScyllaCluster to other networks ` +* :doc:`Deploying multi-datacenter ScyllaDB clusters in Kubernetes ` +* :doc:`Performance tuning [Experimental] ` +* :doc:`Upgrade procedures ` +* :doc:`Releases ` +* :doc:`Support ` +* :doc:`Scylla Cluster Custom Resource Definition (CRD) ` +* :doc:`Contributing to the Scylla Operator Project ` diff --git a/v1.11/_sources/manager.md.txt b/v1.11/_sources/manager.md.txt new file mode 100644 index 00000000000..ce39f6812a5 --- /dev/null +++ b/v1.11/_sources/manager.md.txt @@ -0,0 +1,258 @@ +# Deploying Scylla Manager on a Kubernetes Cluster + +Scylla Manager is a product for database operations automation, +it can schedule tasks such as repairs and backups. +Scylla Manager can manage multiple Scylla clusters and run cluster-wide tasks +in a controlled and predictable way. + +Scylla Manager is available for Scylla Enterprise customers and Scylla Open Source users. +With Scylla Open Source, Scylla Manager is limited to 5 nodes. +See the Scylla Manager [Proprietary Software License Agreement](https://www.scylladb.com/scylla-manager-software-license-agreement/) for details. + +## Prerequisites + +* Kubernetes cluster +* Scylla Operator - see [generic guide](generic.md) + +## Architecture + +Scylla Manager in K8s consist of: +- Dedicated Scylla Cluster + + Scylla Manager persists its state to a Scylla cluster. +Additional small single node cluster is spawned in the Manager namespace. + +- Scylla Manager Controller + + Main mission of Controller is to watch changes of Scylla Clusters, and synchronize three states. + 1. What user wants - task definition in CRD. + 2. What Controller registered - Task name to Task ID mapping - CRD status. + 3. Scylla Manager task listing - internal state of Scylla Manager. + + When Scylla Cluster CRD is being deployed Controller will register it in Scylla Manager once cluster reaches desired node count. +Once Cluster is fully up and running it will schedule all tasks defined in Cluster CRD. +Controller also supports task updates and unscheduling. + +- Scylla Manager + + Regular Scylla Manager, the same used in cloud and bare metal deployments. + + + +## Deploy Scylla Manager + +Deploy the Scylla Manager using the following commands: + +```console +kubectl apply -f examples/common/manager.yaml +``` + +This will install the Scylla Manager in the `scylla-manager` namespace. +You can check if the Scylla Manager is up and running with: + +```console +kubectl -n scylla-manager get pods +NAME READY STATUS RESTARTS AGE +scylla-manager-cluster-manager-dc-manager-rack-0 2/2 Running 0 37m +scylla-manager-controller-0 1/1 Running 0 28m +scylla-manager-scylla-manager-7bd9f968b9-w25jw 1/1 Running 0 37m +``` + +As you can see there are three pods: +* `scylla-manager-cluster-manager-dc-manager-rack-0` - is a single node Scylla cluster. +* `scylla-manager-controller-0` - Scylla Manager Controller. +* `scylla-manager-scylla-manager-7bd9f968b9-w25jw` - Scylla Manager. + +To see if Scylla Manager is fully up and running we can check their logs. +To do this, execute following command: + + ```console +kubectl -n scylla-manager logs scylla-manager-controller-0 +``` + +The output should be something like: +```console +{"L":"INFO","T":"2020-09-23T11:25:27.882Z","M":"Scylla Manager Controller started","version":"","build_date":"","commit":"","built_by":"","go_version":"","options":{"Name":"scylla-manager-controller-0","Namespace":"scylla-manager","LogLevel":"debug","ApiAddress":"http://127.0.0.1:5080/api/v1"},"_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"} +{"L":"INFO","T":"2020-09-23T11:25:28.435Z","M":"Registering Components.","_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"} +``` + +To check logs of Scylla Manager itself, use following command: +```console +kubectl -n scylla-manager logs scylla-manager-scylla-manager-7bd9f968b9-w25jw +``` + +The output should be something like: + +```console +{"L":"INFO","T":"2020-09-23T11:26:53.238Z","M":"Scylla Manager Server","version":"2.1.2-0.20200816.76cc4dcc","pid":1,"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Using config","config":{"HTTP":"127.0.0.1:5080","HTTPS":"","TLSCertFile":"/var/lib/scylla-manager/scylla_manager.crt","TLSKeyFile":"/var/lib/scylla-manager/scylla_manager.key","TLSCAFile":"","Prometheus":":56090","PrometheusScrapeInterval":5000000000,"debug":"127.0.0.1:56112","Logger":{"Mode":"stderr","Level":"info","Development":false},"Database":{"Hosts":["scylla-manager-cluster-manager-dc-manager-rack-0.scylla-manager.svc"],"SSL":false,"User":"","Password":"","LocalDC":"","Keyspace":"scylla_manager","MigrateDir":"/etc/scylla-manager/cql","MigrateTimeout":30000000000,"MigrateMaxWaitSchemaAgreement":300000000000,"ReplicationFactor":1,"Timeout":600000000,"TokenAware":true},"SSL":{"CertFile":"","Validate":true,"UserCertFile":"","UserKeyFile":""},"Healthcheck":{"Timeout":250000000,"SSLTimeout":750000000},"Backup":{"DiskSpaceFreeMinPercent":10,"AgeMax":43200000000000},"Repair":{"SegmentsPerRepair":1,"ShardParallelMax":0,"ShardFailedSegmentsMax":100,"PollInterval":200000000,"ErrorBackoff":300000000000,"AgeMax":0,"ShardingIgnoreMsbBits":12}},"config_files":["/mnt/etc/scylla-manager/scylla-manager.yaml"],"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Checking database connectivity...","_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +``` + +If there are no errors in the logs, let's spin a Scylla Cluster. + +## Cluster registration + + +When the Scylla Manager is fully up and running, lets create a regular instance of Scylla cluster. + +See [generic tutorial](generic.md) to spawn your cluster. + +Note: If you already have some Scylla Clusters, after installing Manager they should be +automatically registered in Scylla Manager. + +Once cluster reaches desired node count, cluster status will be updated with ID under which it was registered in Manager. + + ```console +kubectl -n scylla describe Cluster + +[...] +Status: + Manager Id: d1d532cd-49f2-4c97-9263-25126532803b + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.0.0 +``` +You can use this ID to talk to Scylla Manager using `sctool` CLI installed in Scylla Manager Pod. +You can also use Cluster name in `namespace/cluster-name` format. + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list + +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b) +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮ +│ Task │ Arguments │ Next run │ Status │ +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤ +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b │ │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE │ +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd │ │ 23 Sep 20 14:29:57 CEST (+1m) │ NEW │ +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯ + +``` + +Scylla Manager by default registers recurring healhcheck tasks for Agent and for each of the enabled frontends (CQL, Alternator). + +In this task listing we can see CQL and REST healthchecks. + +## Task scheduling + +You can either define tasks prior Cluster creation, or for existing Cluster. +Let's edit already running cluster definition to add repair and backup task. +```console +kubectl -n scylla edit Cluster simple-cluster +``` + +Add following task definition to Cluster spec: +``` + repairs: + - name: "users repair" + keyspace: ["users"] + interval: "1d" + backups: + - name: "weekly backup" + location: ["s3:cluster-backups"] + retention: 3 + interval: "7d" + - name: "daily backup" + location: ["s3:cluster-backups"] + retention: 7 + interval: "1d" +``` + +For full task definition configuration consult [Scylla Cluster CRD](scylla-cluster-crd.md). + +**Note**: Scylla Manager Agent must have access to above bucket prior the update in order to schedule backup task. +Consult Scylla Manager documentation for details on how to set it up. + +Scylla Manager Controller will spot this change and will schedule tasks in Scylla Manager. + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list + +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b) +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮ +│ Task │ Arguments │ Next run │ Status │ +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤ +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b │ │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE │ +│ backup/275aae7f-c436-4fc8-bcec-479e65fb8372 │ -L s3:cluster-backups --retention 3 │ 23 Sep 20 14:28:58 CEST (+7d) │ NEW │ +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd │ │ 23 Sep 20 14:29:57 CEST (+1m) │ NEW │ +│ repair/d4946360-c29d-4bb4-8b9d-619ada495c2a │ │ 23 Sep 20 14:38:42 CEST │ NEW │ +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯ + +``` + +As you can see, we have two new tasks, weekly recurring backup, and one repair which should start shortly. + +To check progress of run you can use following command: + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task progress --cluster d1d532cd-49f2-4c97-9263-25126532803b repair/d4946360-c29d-4bb4-8b9d-619ada495c2a +Status: RUNNING +Start time: 23 Sep 20 14:38:42 UTC +Duration: 13s +Progress: 2.69% +Datacenters: + - us-east-1 ++--------------------+-------+ +| system_auth | 8.06% | +| system_distributed | 0.00% | +| system_traces | 0.00% | ++--------------------+-------+ + +``` +Other tasks can be also tracked using the same command, but using different task ID. +Task IDs are present in Cluster Status as well as in task listing. + +## Clean Up + +To clean up all resources associated with Scylla Manager, you can run the commands below. + +**NOTE:** this will destroy your Scylla Manager database and delete all of its associated data. + +```console +kubectl delete -f examples/common/manager.yaml +``` + +## Troubleshooting + +**Manager is not running** + +If the Scylla Manager does not come up, the first step would be to examine the Manager and Controller logs: + +```console +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-controller +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-scylla-manager-7bd9f968b9-w25jw +``` + + +**My task wasn't scheduled** + +If your task wasn't scheduled, Cluster status will be updated with error messages for each failed task. +You can also consult Scylla Manager logs. + +Example: + +Following status describes error when backup task cannot be scheduled, due to lack of access to bucket: +```console +Status: + Backups: + Error: create backup target: location is not accessible: 10.100.16.62: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.100.16.62 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.107.193.33: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.107.193.33 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.109.197.60: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.109.197.60 and run "scylla-manager-agent check-location -L s3:manager-test --debug" + Id: 00000000-0000-0000-0000-000000000000 + Interval: 0 + Location: + s3:manager-test + Name: adhoc backup + Num Retries: 3 + Retention: 3 + Start Date: now + Manager Id: 2b9dbe8c-9daa-4703-a66d-c29f63a917c8 + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.0.0 +``` + +Because Controller is infinitely retrying to schedule each defined task, once permission issues will be resolved, +task should appear in task listing and Cluster status. \ No newline at end of file diff --git a/v1.11/_sources/migration.md.txt b/v1.11/_sources/migration.md.txt new file mode 100644 index 00000000000..cdd7a7e8522 --- /dev/null +++ b/v1.11/_sources/migration.md.txt @@ -0,0 +1,146 @@ +## Version migrations + + +### `v0.3.0` -> `v1.0.0` migration + +`v0.3.0` used a very common name as a CRD kind (`Cluster`). In `v1.0.0` this issue was solved by using less common kind +which is easier to disambiguate (`ScyllaCluster`). +***This change is backward incompatible, which means manual migration is needed.*** + +This procedure involves having two CRDs registered at the same time. We will detach Scylla Pods +from Scylla Operator for a short period to ensure that nothing is garbage collected when Scylla Operator is upgraded. +Compared to the [upgrade guide](upgrade.md) where full deletion is requested, this procedure shouldn't cause downtimes. +Although detaching resources from their controller is considered hacky. This means that you shouldn't run procedure +out of the box on production. Make sure this procedure works well multiple times on your staging environment first. + +***Read the whole procedure and make sure you understand what is going on before executing any of the commands!*** + +In case of any issues or questions regarding this procedure, you're welcomed on our [Scylla Users Slack](http://slack.scylladb.com/) +on #kubernetes channel. + +### Procedure + +1. Execute this whole procedure for each cluster sequentially. To get a list of existing clusters execute the following + ``` + kubectl -n scylla get cluster.scylla.scylladb.com + + NAME AGE + simple-cluster 30m + ``` + All below commands will use `scylla` namespace and `simple-cluster` as a cluster name. +1. Make sure you're using v1.0.0 tag: + ``` + git checkout v1.0.0 + ``` +1. Upgrade your `cert-manager` to `v1.0.0`. If you installed it from a static file from this repo, simply execute the following: + ``` + kubectl apply -f examples/common/cert-manager.yaml + ``` + If your `cert-manager` was installed in another way, follow official instructions on `cert-manager` website. +1. `examples/common/operator.yaml` file contains multiple resources. Extract **only** `CustomResourceDefinition` to separate file. +1. Install v1.0.0 CRD definition from file created in the previous step: + ``` + kubectl apply -f examples/common/crd.yaml + ``` +1. Save your existing `simple-cluster` Cluster definition to a file: + ``` + kubectl -n scylla get cluster.scylla.scylladb.com simple-cluster -o yaml > existing-cluster.yaml + ``` +1. Migrate `Kind` and `ApiVersion` to new values using: + ``` + sed -i 's/scylla.scylladb.com\/v1alpha1/scylla.scylladb.com\/v1/g' existing-cluster.yaml + sed -i 's/kind: Cluster/kind: ScyllaCluster/g' existing-cluster.yaml + ``` +1. Install migrated CRD instance + ``` + kubectl apply -f existing-cluster.yaml + ``` + At this point, we should have two CRDs describing your Scylla cluster, although the new one is not controlled by the Operator. +1. Get UUID of newly created ScyllaCluster resource: + ``` + kubectl -n scylla get ScyllaCluster simple-cluster --template="{{ .metadata.uid }}" + + 12a3678d-8511-4c9c-8a48-fa78d3992694 + ``` + Save output UUID somewhere, it will be referred as `` in commands below. + + ***Depending on your shell, you might get additional '%' sign at the end of UUID, make sure to remove it!*** + +1. Upgrade ClusterRole attached to each of the Scylla nodes to grant them permission to lookup Scylla clusters: + ``` + kubectl patch ClusterRole simple-cluster-member --type "json" -p '[{"op":"add","path":"/rules/-","value":{"apiGroups":["scylla.scylladb.com"],"resources":["scyllaclusters"],"verbs":["get"]}}]' + ``` + Amend role name according to your cluster name, it should look like `-member`. +1. Get a list of all Services associated with your cluster. First get list of all services: + ``` + kubectl -n scylla get svc -l "scylla/cluster=simple-cluster" + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 109m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.23.96 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 109m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.66.22 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 108m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.246.25 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 106m + + ``` +1. For each service, change its `ownerReference` to point to new CRD instance: + ``` + kubectl -n scylla patch svc --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":""}]' + ``` + Replace `` with Service name, and `` with saved UUID from one of the previous steps. +1. Get a list of all Services again to see if none was deleted. Check also "Age" column, it shouldn't be lower than previous result. + ``` + kubectl -n scylla get svc -l "scylla/cluster=simple-cluster" + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 110m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.23.96 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 110m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.66.22 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 109m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.246.25 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 107m + + ``` +1. Get a list of StatefulSets associated with your cluster: + ``` + kubectl -n scylla get sts -l "scylla/cluster=simple-cluster" + + NAME READY AGE + simple-cluster-us-east-1-us-east-1a 3/3 104m + ``` +1. For each StatefulSet from previous step, change its `ownerReference` to point to new CRD instance. + + ``` + kubectl -n scylla patch sts --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":""}]' + ``` + Replace `` with StatefulSet name, and `` with saved UUID from one of the previous steps. + +1. Now when all k8s resources bound to Scylla are attached to new CRD, we can remove 0.3.0 Operator and old CRD definition. + Checkout `v0.3.0` version, and remove Scylla Operator, and old CRD: + ``` + git checkout v0.3.0 + kubectl delete -f examples/generic/operator.yaml + ``` +1. Checkout `v1.0.0`, and install upgraded Scylla Operator: + ``` + git checkout v1.0.0 + kubectl apply -f examples/common/operator.yaml + ``` +1. Wait until Scylla Operator boots up: + ``` + kubectl -n scylla-operator-system wait --for=condition=ready pod --all --timeout=600s + ``` +1. Get a list of StatefulSets associated with your cluster: + ``` + kubectl -n scylla get sts -l "scylla/cluster=simple-cluster" + + NAME READY AGE + simple-cluster-us-east-1-us-east-1a 3/3 104m +1. For each StatefulSet from previous step, change its sidecar container image to `v1.0.0`, and wait until change will be propagated. This step will initiate a rolling restart of pods one by one. + ``` + kubectl -n scylla patch sts --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/initContainers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]' + kubectl -n scylla rollout status sts + ``` + Replace `` with StatefulSet name. +1. If you're using Scylla Manager, bump Scylla Manager Controller image to `v1.0.0` + ``` + kubectl -n scylla-manager-system patch sts scylla-manager-controller --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]' + ``` +1. Your Scylla cluster is now migrated to `v1.0.0`. diff --git a/v1.11/_sources/monitoring.md.txt b/v1.11/_sources/monitoring.md.txt new file mode 100644 index 00000000000..9f2651c5737 --- /dev/null +++ b/v1.11/_sources/monitoring.md.txt @@ -0,0 +1,180 @@ +# Monitoring + +Scylla Operator 1.8 introduced a new API resource `ScyllaDBMonitoring`, allowing users to deploy a managed monitoring +setup for their Scylla Clusters. + +```yaml +apiVersion: scylla.scylladb.com/v1alpha1 +kind: ScyllaDBMonitoring +metadata: + name: example +spec: + type: Platform + endpointsSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla-operator.scylladb.com/scylla-service-type: identity + scylla/cluster: replace-with-your-scyllacluster-name + components: + prometheus: + storage: + volumeClaimTemplate: + spec: + resources: + requests: + storage: 1Gi + grafana: + exposeOptions: + webInterface: + ingress: + ingressClassName: haproxy + dnsDomains: + - test-grafana.test.svc.cluster.local + annotations: + haproxy-ingress.github.io/ssl-passthrough: "true" +``` + +For details, refer to the below command: +```console +$ kubectl explain scylladbmonitorings.scylla.scylladb.com/v1alpha1 +``` + +## Deploy managed monitoring + +**Note**: as of v1.8, ScyllaDBMonitoring is experimental. The API is currently in version v1alpha1 and may change in future versions. + +### Requirements + +Before you can set up your ScyllaDB monitoring, you need Scylla Operator already installed in your Kubernetes cluster. +For more information on how to deploy Scylla Operator, see: +* [Deploying Scylla on a Kubernetes Cluster](generic.md) +* [Deploying Scylla stack using Helm Charts](helm.md) + +The above example of the monitoring setup also makes use of HAProxy Ingress and Prometheus Operator. +You can deploy them in your Kubernetes cluster using the provided third party examples. If you already have them deployed +in your cluster, you can skip the below steps. + +#### Deploy Prometheus Operator +Deploy Prometheus Operator using kubectl: +```console +$ kubectl -n prometheus-operator apply --server-side -f ./examples/third-party/prometheus-operator +``` + +##### Wait for Prometheus Operator to roll out +```console +$ kubectl -n prometheus-operator rollout status --timeout=5m deployments.apps/prometheus-operator +deployment "prometheus-operator" successfully rolled out +``` + +#### Deploy HAProxy Ingress +Deploy HAProxy Ingress using kubectl: +```console +$ kubectl -n haproxy-ingress apply --server-side -f ./examples/third-party/haproxy-ingress +``` + +##### Wait for HAProxy Ingress to roll out +```console +$ kubectl -n haproxy-ingress rollout status --timeout=5m deployments.apps/haproxy-ingress +deployment "haproxy-ingress" successfully rolled out +``` + +### Deploy ScyllaDBMonitoring + +First, update the `endpointsSelector` in `examples/monitoring/v1alpha1/scylladbmonitoring.yaml` with a label +matching your ScyllaCluster instance name. + +Deploy the monitoring setup using kubectl: +```console +$ kubectl -n scylla apply --server-side -f ./examples/monitoring/v1alpha1/scylladbmonitoring.yaml +``` + +Scylla Operator will notice the new ScyllaDBMonitoring object, and it will reconcile all necessary resources. + +#### Wait for ScyllaDBMonitoring to roll out +```console +$ kubectl wait --for='condition=Progressing=False' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met + +$ kubectl wait --for='condition=Degraded=False' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met + +$ kubectl wait --for='condition=Available=True' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met +``` + +#### Wait for Prometheus to roll out +```console +$ kubectl rollout status --timeout=5m statefulset.apps/prometheus-example +statefulset rolling update complete 1 pods at revision prometheus-example-65b89d55bb... +``` + +#### Wait for Grafana to roll out +```console +$ kubectl rollout status --timeout=5m deployments.apps/example-grafana +deployment "example-grafana" successfully rolled out +``` + +### Accessing Grafana + +For accessing Grafana service from outside the Kubernetes cluster we recommend using an Ingress, although there are many other ways to do so. +When using Ingress, what matters is to direct your packets to the ingress controller Service/Pods and have the correct TLS SNI field set by the caller when reaching out to the service, so it is routed properly, and your client can successfully validate the grafana serving certificate. +This is easier when you are using a real DNS domain that resolves to your Ingress controller's IP address but most clients and tools allow setting the SNI field manually. + +### Prerequisites + +To access Grafana, you first need to collect the serving CA and the credentials. + +```console +$ GRAFANA_SERVING_CERT="$( kubectl -n scylla get secret/example-grafana-serving-ca --template '{{ index .data "tls.crt" }}' | base64 -d )" +$ GRAFANA_USER="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "username" }}' | base64 -d )" +$ GRAFANA_PASSWORD="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "password" }}' | base64 -d )" +``` + +### Connecting through Ingress using a resolvable domain + +In production clusters, the Ingress controller and appropriate DNS records should be set up already. Often there is already a generic wildcard record like `*.app.mydomain` pointing to the Ingress controller's external IP. For custom service domains, it is usually a CNAME pointing to the Ingress controller's A record. + +Note: The ScyllaDBMonitoring example creates an Ingress object with `test-grafana.test.svc.cluster.local` DNS domain that you should adjust to your domain. Below examples use `example-grafana.apps.mydomain`. + +Note: To test a resolvable domain from your machine without creating DNS records, you can adjust `/etc/hosts` or similar. + +```console +$ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://example-grafana.apps.mydomain" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}" +200 +``` + +### Connecting through Ingress using an unresolvable domain + +To connect to an Ingress without a resolvable domain you first need to find out your Ingress controller's IP that can be resolved externally. Again, there are many ways to do so beyond the below examples. + +Unless stated otherwise, we assume your Ingress is running on port 443. + +```console +$ INGRESS_PORT=443 +``` + +#### Variants + +##### Ingress ExternalIP + +When you are running in a real cluster there is usually a cloud LoadBalancer or a bare metal alternative providing you with an externally reachable IP address. + +```console +$ INGRESS_IP="$( kubectl -n=haproxy-ingress get service/haproxy-ingress --template='{{ ( index .status.loadBalancer.ingress 0 ).ip }}' )" +``` + +##### Ingress NodePort + +NodePort is slightly less convenient, but it's available in development clusters as well. + +```console +$ INGRESS_IP="$( kubectl get nodes --template='{{ $internal_ip := "" }}{{ $external_ip := "" }}{{ range ( index .items 0 ).status.addresses }}{{ if eq .type "InternalIP" }}{{ $internal_ip = .address }}{{ else if eq .type "ExternalIP" }}{{ $external_ip = .address }}{{ end }}{{ end }}{{ if $external_ip }}{{ $external_ip }}{{ else }}{{ $internal_ip }}{{ end }}' )" +$ INGRESS_PORT="$( kubectl -n=haproxy-ingress get services/haproxy-ingress --template='{{ range .spec.ports }}{{ if eq .port 443 }}{{ .nodePort }}{{ end }}{{ end }}' )" +``` + +##### Connection + +```console +$ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://test-grafana.test.svc.cluster.local:${INGRESS_PORT}" --resolve "test-grafana.test.svc.cluster.local:${INGRESS_PORT}:${INGRESS_IP}" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}" +200 +``` diff --git a/v1.11/_sources/multidc/eks.md.txt b/v1.11/_sources/multidc/eks.md.txt new file mode 100644 index 00000000000..266dd7d3a4d --- /dev/null +++ b/v1.11/_sources/multidc/eks.md.txt @@ -0,0 +1,168 @@ +# Build multiple Amazon EKS clusters with inter-Kubernetes networking + +This document describes the process of creating multiple Amazon EKS clusters in different regions, using separate VPCs, and explains the steps necessary for configuring inter-Kubernetes networking between the clusters. +The interconnected clusters can serve as a platform for [deploying a multi-datacenter ScyllaDB cluster](multidc.md). + +This guide will walk you through the process of creating and configuring EKS clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference. + +## Prerequisites + +To follow the below guide, you first need to install and configure the tools that you will need to create and manage AWS and Kubernetes resources: +- eksctl – A command line tool for working with EKS clusters. +- kubectl – A command line tool for working with Kubernetes clusters. + +For more information see [Getting started with Amazon EKS – eksctl](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html) in AWS documentation. + +## Create EKS clusters + +### Create the first EKS cluster + +Below is the required specification for the first cluster. + +```yaml +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig + +metadata: + name: scylladb-us-east-1 + region: us-east-1 + +availabilityZones: +- us-east-1a +- us-east-1b +- us-east-1c + +vpc: + cidr: 10.0.0.0/16 + +nodeGroups: + ... +``` + +Specify the first cluster's configuration file and save it as `cluster-us-east-1.yaml`. +Refer to [Creating an EKS cluster](../eks.md#creating-an-eks-cluster) section of ScyllaDB Operator documentation for the reference of the configuration of node groups. + +To deploy the first cluster, use the below command: +```shell +eksctl create cluster -f=cluster-us-east-1.yaml +``` + +Run the following command to learn the status and VPC ID of the cluster: +```shell +eksctl get cluster --name=scylladb-us-east-1 --region=us-east-1 +``` + +You will need to get the cluster's context for future operations. To do so, use the below command: +```shell +kubectl config current-context +``` + +For any `kubectl` commands that you will want to run against this cluster, use the `--context` flag with the value returned by the above command. + +#### Deploy ScyllaDB Operator + +Once the cluster is ready, refer to [Deploying Scylla on a Kubernetes Cluster](../generic.md) to deploy the ScyllaDB Operator and its prerequisites. + +#### Prepare nodes for running ScyllaDB + +Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in [Deploying Scylla on EKS](../eks.md#prerequisites) in ScyllaDB Operator documentation. + +### Create the second EKS cluster + +Below is the required specification for the second cluster. As was the case with the first cluster, the provided values are only exemplary and can be adjusted according to your needs. + +:::{caution} +It is required that the VPCs of the two EKS clusters have non-overlapping IPv4 network ranges. +::: + +```yaml +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig + +metadata: + name: scylladb-us-east-2 + region: us-east-2 + +availabilityZones: +- us-east-2a +- us-east-2b +- us-east-2c + +vpc: + cidr: 172.16.0.0/16 + +nodeGroups: + ... +``` + +Follow analogous steps to create the second EKS cluster and prepare it for running ScyllaDB. + +## Configure the network + +The prepared Kubernetes clusters each have a dedicated VPC network. +To be able to route the traffic between the two VPC networks, you need to create a networking connection between them, otherwise known as [VPC peering](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html). + +### Create VPC peering + +Refer to [Create a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/create-vpc-peering-connection.html#create-vpc-peering-connection-local) in AWS documentation for instructions on creating a VPC peering connection between the two earlier created VPCs. + +In this example, the ID of the created VPC peering connection is `pcx-08077dcc008fbbab6`. + +### Update route tables + +To enable private IPv4 traffic between the instances in the VPC peered network, you need to establish a communication channel by adding a route to the route tables associated with all the subnets associated with the instances for both VPCs. +The destination of the new route in a given route table is the CIDR of the VPC of the other cluster and the target is the ID of the VPC peering connection. + +The following is an example of the route tables that enable communication of instances in two peered VPCs. Each table has a local route and the added route which sends traffic targeted at the other VPC to the peered network connection. The other preconfigured routes are omitted for readability. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          Route tableDestinationTarget
          eksctl-scylladb-us-east-1-cluster/PublicRouteTable10.0.0.0/16local
          172.16.0.0/16pcx-08077dcc008fbbab6
          eksctl-scylladb-us-east-2-cluster/PublicRouteTable172.16.0.0/16local
          10.0.0.0/16pcx-08077dcc008fbbab6
          + + +Refer to [Update your route tables for a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-routing.html) in AWS documentation for more information. + +### Update security groups + +To allow traffic to flow to and from instances associated with security groups in the peered VPC, you need to update the inbound rules of the VPCs' shared security groups. + +Below is an example of the inbound rules that to be added to the corresponding security groups of the two VPCs. + +| Security group name | Type | Protocol | Port range | Source | +|--------------------------------------------------------------------------------|-------------|----------|------------|----------------------| +| eksctl-scylladb-us-east-1-cluster-ClusterSharedNodeSecurityGroup-TD05V9EVU3B8 | All traffic | All | All | Custom 172.16.0.0/16 | +| eksctl-scylladb-us-east-2-cluster-ClusterSharedNodeSecurityGroup-1FR9YDLU0VE7M | All traffic | All | All | Custom 10.0.0.0/16 | + +The names of the shared security groups of your VPCs should be similar to the ones presented in the example. + +--- + +Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to [Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters](multidc.md) in ScyllaDB Operator documentation for guidance. diff --git a/v1.11/_sources/multidc/gke.md.txt b/v1.11/_sources/multidc/gke.md.txt new file mode 100644 index 00000000000..b119d9e9b3b --- /dev/null +++ b/v1.11/_sources/multidc/gke.md.txt @@ -0,0 +1,156 @@ +# Build multiple GKE clusters with inter-Kubernetes networking + +This document describes the process of creating multiple GKE clusters in a shared VPC and explains the steps necessary for configuring inter-Kubernetes networking between clusters in different regions. +The interconnected clusters can serve as a platform for [deploying a Multi Datacenter ScyllaDB cluster](multidc.md). + +This guide will walk you through the process of creating and configuring GKE clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference. + +## Prerequisites + +To follow the below guide, you first need to install and configure the following tools that you will need to create and manage GCP and Kubernetes resources: +- gcloud CLI - Google Cloud Command Line Interface, a command line tool for working with Google Cloud resources and services directly. +- kubectl – A command line tool for working with Kubernetes clusters. + +See [Install the Google Cloud CLI](https://cloud.google.com/sdk/docs/install-sdk) in GCP documentation and [Install Tools](https://kubernetes.io/docs/tasks/tools/) in Kubernetes documentation for reference. + +## Create and configure a VPC network + +For the clusters to have inter-Kubernetes networking, you will create a virtual network shared between all the instances, with dedicated subnets for each of the clusters. +To create the subnets manually, create the network in custom subnet mode. + +### Create the VPC network + +Run the below command to create the network: +```shell +gcloud compute networks create scylladb --subnet-mode=custom +``` + +With the VPC network created, create a dedicated subnet with secondary CIDR ranges for their Pod and Service pools in each region which the clusters will reside in. + +### Create VPC network subnets + +To create a subnet for the first cluster in region `us-east1`, run the below command: +```shell +gcloud compute networks subnets create scylladb-us-east1 \ + --region=us-east1 \ + --network=scylladb \ + --range=10.0.0.0/20 \ + --secondary-range='cluster=10.1.0.0/16,services=10.2.0.0/20' +``` + +To create a subnet for the second cluster in region `us-west1`, run the below command: +```shell +gcloud compute networks subnets create scylladb-us-west1 \ + --region=us-west1 \ + --network=scylladb \ + --range=172.16.0.0/20 \ + --secondary-range='cluster=172.17.0.0/16,services=172.18.0.0/20' +``` + +:::{caution} +It is required that the IPv4 address ranges of the subnets allocated for the GKE clusters do not overlap. +::: + +Refer to [Create a VPC-native cluster](https://cloud.google.com/kubernetes-engine/docs/how-to/alias-ips) and [Alias IP ranges](https://cloud.google.com/vpc/docs/alias-ip) in GKE documentation for more information about VPC native clusters and alias IP ranges. + +## Create GKE clusters + +With the VPC network created, you will now create two VPC native GKE clusters in dedicated regions. + +### Create the first GKE cluster + +Run the following command to create the first GKE cluster in the `us-east1` region: +```shell +gcloud container clusters create scylladb-us-east1 \ + --location=us-east1-b \ + --node-locations='us-east1-b,us-east1-c' \ + --machine-type=n1-standard-8 \ + --num-nodes=1 \ + --disk-type=pd-ssd \ + --disk-size=20 \ + --image-type=UBUNTU_CONTAINERD \ + --no-enable-autoupgrade \ + --no-enable-autorepair \ + --enable-ip-alias \ + --network=scylladb \ + --subnetwork=scylladb-us-east1 \ + --cluster-secondary-range-name=cluster \ + --services-secondary-range-name=services +``` + +Refer to [Creating a GKE cluster](../gke.md#creating-a-gke-cluster) section of ScyllaDB Operator documentation for more information regarding the configuration and deployment of additional node pools, including the one dedicated for ScyllaDB nodes. + +You will need to get the cluster's context for future operations. To do so, use the below command: +```shell +kubectl config current-context +``` + +For any `kubectl` commands that you will want to run against this cluster, use the `--context` flag with the value returned by the above command. + +#### Deploy ScyllaDB Operator + +Once the cluster is ready, refer to [Deploying Scylla on a Kubernetes Cluster](../generic.md) to deploy the ScyllaDB Operator and its prerequisites. + +#### Prepare nodes for running ScyllaDB + +Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in [Deploying Scylla on GKE](../gke.md) page of the documentation. + +### Create the second GKE cluster + +Run the following command to create the second GKE cluster in the `us-west1` region: +```shell +gcloud container clusters create scylladb-us-west1 \ + --location=us-west1-b \ + --node-locations='us-west1-b,us-west1-c' \ + --machine-type=n1-standard-8 \ + --num-nodes=1 \ + --disk-type=pd-ssd \ + --disk-size=20 \ + --image-type=UBUNTU_CONTAINERD \ + --no-enable-autoupgrade \ + --no-enable-autorepair \ + --enable-ip-alias \ + --network=scylladb \ + --subnetwork=scylladb-us-west1 \ + --cluster-secondary-range-name=cluster \ + --services-secondary-range-name=services +``` + +Follow analogous steps to create the second GKE cluster and prepare it for running ScyllaDB. + +## Configure the firewall rules + +When creating a cluster, GKE creates several ingress firewall rules that enable the instances to communicate with each other. +To establish interconnectivity between the two created Kubernetes clusters, you will now add the allocated IPv4 address ranges to their corresponding source address ranges. + +First, retrieve the name of the firewall rule associated with the first cluster, which permits traffic between all Pods on a cluster, as required by the Kubernetes networking model. +The rule name is in the following format: `gke-[cluster-name]-[cluster-hash]-all`. + +To retrieve it, run the below command: +```shell +gcloud compute firewall-rules list --filter='name~gke-scylladb-us-east1-.*-all' +``` + +The output should resemble the following: +```console +NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED +gke-scylladb-us-east1-f17db261-all scylladb INGRESS 1000 udp,icmp,esp,ah,sctp,tcp False +``` + +Modify the rule by updating the rule's source ranges with the allocated Pod IPv4 address ranges of both clusters: +```shell +gcloud compute firewall-rules update gke-scylladb-us-east1-f17db261-all --source-ranges='10.1.0.0/16,172.17.0.0/16' +``` + +Follow the analogous steps for the other cluster. In this example, its corresponding firewall rule name is `gke-scylladb-us-west1-0bb60902-all`. To update it, you would run: +```shell +gcloud compute firewall-rules update gke-scylladb-us-west1-0bb60902-all --source-ranges='10.1.0.0/16,172.17.0.0/16' +``` + +Refer to [Automatically created firewall rules](https://cloud.google.com/kubernetes-engine/docs/concepts/firewall-rules) in GKE documentation for more information. + +--- + +Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to [Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters](multidc.md) in ScyllaDB Operator documentation for guidance. diff --git a/v1.11/_sources/multidc/index.rst.txt b/v1.11/_sources/multidc/index.rst.txt new file mode 100644 index 00000000000..52a87126e8a --- /dev/null +++ b/v1.11/_sources/multidc/index.rst.txt @@ -0,0 +1,25 @@ +========================================================== +Deploying multi-datacenter ScyllaDB clusters in Kubernetes +========================================================== + +Prepare a platform for a multi datacenter ScyllaDB cluster deployment: + +.. toctree:: + :hidden: + :maxdepth: 2 + + eks + gke + +* :doc:`Build multiple Amazon EKS clusters with Inter-Kubernetes networking ` +* :doc:`Build multiple GKE clusters with Inter-Kubernetes networking ` + +Deploy a multi-datacenter ScyllaDB cluster in Kubernetes: + +.. toctree:: + :hidden: + :maxdepth: 2 + + multidc + +* :doc:`Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters ` diff --git a/v1.11/_sources/multidc/multidc.md.txt b/v1.11/_sources/multidc/multidc.md.txt new file mode 100644 index 00000000000..33435f7ab22 --- /dev/null +++ b/v1.11/_sources/multidc/multidc.md.txt @@ -0,0 +1,601 @@ +# Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters + +This document describes the process of deploying a Multi Datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters. + +This guide will walk you through the example procedure of deploying two datacenters in distinct regions of a selected cloud provider. + +:::{note} +This guide is dedicated to deploying multi-datacenter ScyllaDB clusters and does not discuss unrelated configuration options. +For details of ScyllaDB cluster deployments and their configuration, refer to [Deploying Scylla on a Kubernetes Cluster](../generic.md) in ScyllaDB Operator documentation. +::: + +## Prerequisites + +As this document describes the procedure of deploying a Multi Datacenter ScyllaDB cluster, you are expected to have the required infrastructure prepared. +Let's assume two interconnected Kubernetes clusters, capable of communicating with each other over PodIPs, with each cluster meeting the following requirements: +- a node pool dedicated to ScyllaDB nodes composed of at least 3 nodes running in different zones (with unique `topology.kubernetes.io/zone` label), configured to run ScyllaDB, each labeled with `scylla.scylladb.com/node-type: scylla` +- running ScyllaDB Operator and its prerequisites +- running a storage provisioner capable of provisioning XFS volumes of StorageClass `scylladb-local-xfs` in each of the nodes dedicated to ScyllaDB instances + +You can refer to one of our guides describing the process of preparing such infrastructure: +- [Build multiple Amazon EKS clusters with Inter-Kubernetes networking](eks.md) +- [Build multiple GKE clusters with Inter-Kubernetes networking](gke.md) + +Additionally, to follow the below guide, you need to install and configure the following tools that you will need to manage Kubernetes resources: +- kubectl – A command line tool for working with Kubernetes clusters. + +See [Install Tools](https://kubernetes.io/docs/tasks/tools/) in Kubernetes documentation for reference. + +## Multi Datacenter ScyllaDB Cluster + +In v1.11, ScyllaDB Operator introduced support for manual multi-datacenter ScyllaDB cluster deployments. + +:::{warning} +ScyllaDB Operator only supports *manual configuration* of multi-datacenter ScyllaDB clusters. +In other words, although ScyllaCluster API exposes the machinery necessary for setting up multi-datacenter ScylaDB clusters, the ScyllaDB Operator only automates operations for a single datacenter. + +Operations related to multiple datacenters may require manual intervention of a human operator. +Most notably, destroying one of the Kubernetes clusters or ScyllaDB datacenters is going to leave DN nodes behind in other datacenters, and their removal has to be carried out manually. +::: + +The main mechanism used to set up a manual multi-datacenter ScyllaDB cluster is a field in ScyllaCluster's specification - `externalSeeds`. + +### External seeds + +The `externalSeeds` field in ScyllaCluster's specification enables control over external seeds that are propagated to ScyllaDB binary as `--seed-provider-parameters seeds=`. +In this context, external should be understood as "external to the datacenter being specified by the API". +The provided seeds are used by the nodes as initial points of contact, which allows them to discover the cluster ring topology when joining it. + +Refer to [Scylla Seed Nodes](https://opensource.docs.scylladb.com/stable/kb/seed-nodes.html) in ScyllaDB documentation for more information regarding the function of seed nodes in ScyllaDB. +For more details regarding the function and implementation of external seeds, refer to [the original enhancement proposal](https://github.com/scylladb/scylla-operator/tree/v1.11/enhancements/proposals/1304-external-seeds). + +### Networking + +Since this guide assumes interconnectivity over PodIPs of the Kubernetes clusters, you are going to configure the ScyllaDB cluster's nodes to communicate over PodIPs. +This is enabled by a subset of `exposeOptions` specified in ScyllaCluster API, introduced in v1.11. + +For this particular setup, define the ScyllaClusers as follows: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +spec: + exposeOptions: + nodeService: + type: Headless + broadcastOptions: + clients: + type: PodIP + nodes: + type: PodIP +``` + +However, other configuration options allow for the manual deployment of multi-datacenter ScyllaDB clusters in different network setups. For details, refer to [Exposing ScyllaClusters](../exposing.md) in ScyllaDB Operator documentation. + +#### Deploy a multi-datacenter ScyllaDB Cluster + +#### Using context + +Let's specify contexts for `kubectl` commands used throughout the guide. +To retrieve the context of your current cluster, run: +```shell +kubectl config current-context +``` + +Save the contexts of the two clusters, which you are going to deploy the datacenters in, as `CONTEXT_DC1` and `CONTEXT_DC2` environment variables correspondingly. + +#### Deploy the first datacenter + +First, run the below command to create a dedicated 'scylla' namespace: +```shell +kubectl --context="${CONTEXT_DC1}" create ns scylla +``` + +For this guide, let's assume that your cluster is running in `us-east-1` region and the nodes dedicated to running ScyllaDB nodes are running in zones `us-east-1a`, `us-east-1b` and `us-east-1c` correspondingly. If that is not the case, adjust the manifest accordingly. + +:::{caution} +The `.spec.name` field of the ScyllaCluster objects represents the ScyllaDB cluster name and has to be consistent across all datacenters of this ScyllaDB cluster. +The names of the datacenters, specified in `.spec.datacenter.name`, have to be unique across the entire multi-datacenter cluster. + +For more information see [Create a ScyllaDB Cluster - Multi Data Centers (DC)](https://opensource.docs.scylladb.com/stable/operating-scylla/procedures/cluster-management/create-cluster-multidc.html) in ScyllaDB documentation. +::: + +Save the ScyllaCluster manifest in `dc1.yaml`: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: scylla-cluster + namespace: scylla +spec: + version: 5.2.7 + agentVersion: 3.1.2 + cpuset: true + sysctls: + - "fs.aio-max-nr=2097152" + automaticOrphanedNodeCleanup: true + exposeOptions: + broadcastOptions: + clients: + type: PodIP + nodes: + type: PodIP + nodeService: + type: Headless + datacenter: + name: us-east-1 + racks: + - name: a + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-1a + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule + - name: b + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-1b + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule + - name: c + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-1c + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule +``` + +Apply the manifest: +```shell +kubectl --context="${CONTEXT_DC1}" apply --server-side -f=dc1.yaml +``` + +Wait for the cluster to be fully rolled out: +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +You can now verify that all the nodes of your cluster are in UN state: +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla exec -it pod/scylla-cluster-us-east-1-a-0 -c=scylla -- nodetool status +``` + +The expected output should look similar to the below: +```console +Datacenter: us-east-1 +===================== +Status=Up/Down +|/ State=Normal/Leaving/Joining/Moving +-- Address Load Tokens Owns Host ID Rack +UN 10.0.70.195 290 KB 256 ? 494277b9-121c-4af9-bd63-3d0a7b9305f7 c +UN 10.0.59.24 559 KB 256 ? a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37 b +UN 10.0.19.237 107 KB 256 ? 64b6292a-327f-4128-852a-6004039f402e a +``` + +##### Retrieve PodIPs of ScyllaDB nodes for use as external seeds + +:::{warning} +Due to the ephemeral nature of PodIPs, it is ill-advised to use them as seeds in production environments. +This is because there is a high likelihood that the Pods of your ScyllaDB clusters will change their IPs during the cluster's lifecycle, and so the provided seeds will no longer point to the ScyllaDB nodes. +It is undesired, as the seeds provided on node's startup may serve as fallback contact points when all of the node's peers are unreachable. +In production environments, it is recommended that you use domain names or non-ephemeral IP addresses as external seeds. +PodIPs are being used in this example for the sheer simplicity of this setup. +::: + +Use the below commands and their expected outputs as a reference for retrieving the PodIPs used by the cluster for inter-node communication. +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-a-0 --template='{{ .status.podIP }}' +``` +```console +10.0.19.237 +``` + +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-b-0 --template='{{ .status.podIP }}' +``` +```console +10.0.59.24 +``` + +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-c-0 --template='{{ .status.podIP }}' +``` +```console +10.0.70.195 +``` + +You are going to utilize the retrieved addresses as seeds for the other datacenter. + +#### Deploy the second datacenter + +To deploy the second datacenter, you will follow similar steps. + +First, create a dedicated 'scylla' namespace: +```shell +kubectl --context="${CONTEXT_DC2}" create ns scylla +``` + +Replace the values in `.spec.externalSeeds` of the below manifest with the Pod IP addresses that you retrieved earlier. +The provided values are going to serve as initial contact points for the joining nodes of the second datacenter. + +For this guide, let's assume that the second cluster is running in `us-east-2` region and the nodes dedicated for running ScyllaDB nodes are running in zones `us-east-2a`, `us-east-2b` and `us-east-2c` correspondingly. If that is not the case, adjust the manifest accordingly. +Having configured it, save the manifest as `dc2.yaml`: +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: scylla-cluster + namespace: scylla +spec: + version: 5.2.7 + agentVersion: 3.1.2 + cpuset: true + sysctls: + - "fs.aio-max-nr=2097152" + automaticOrphanedNodeCleanup: true + exposeOptions: + broadcastOptions: + clients: + type: PodIP + nodes: + type: PodIP + nodeService: + type: Headless + externalSeeds: + - 10.0.19.237 + - 10.0.59.24 + - 10.0.70.195 + datacenter: + name: us-east-2 + racks: + - name: a + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-2a + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule + - name: b + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-2b + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule + - name: c + members: 1 + storage: + storageClassName: scylladb-local-xfs + capacity: 1800G + agentResources: + requests: + cpu: 100m + memory: 250M + limits: + cpu: 100m + memory: 250M + resources: + requests: + cpu: 7 + memory: 56G + limits: + cpu: 7 + memory: 56G + placement: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla/cluster: scylla-cluster + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - us-east-2c + - key: scylla.scylladb.com/node-type + operator: In + values: + - scylla + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule +``` + +To apply the manifest, run: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla apply --server-side -f=dc2.yaml +``` + +Wait for the second datacenter to roll out: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster +``` +```console +scyllacluster.scylla.scylladb.com/scylla-cluster condition met +``` + +You can verify that the nodes have joined the existing cluster and that you are now running a multi-datacenter ScyllaDB cluster by running `nodetool status` with the below command: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla exec -it pod/scylla-cluster-us-east-2-a-0 -c=scylla -- nodetool status +``` +```console +Datacenter: us-east-1 +===================== +Status=Up/Down +|/ State=Normal/Leaving/Joining/Moving +-- Address Load Tokens Owns Host ID Rack +UN 10.0.70.195 705 KB 256 ? 494277b9-121c-4af9-bd63-3d0a7b9305f7 c +UN 10.0.59.24 764 KB 256 ? a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37 b +UN 10.0.19.237 634 KB 256 ? 64b6292a-327f-4128-852a-6004039f402e a +Datacenter: us-east-2 +===================== +Status=Up/Down +|/ State=Normal/Leaving/Joining/Moving +-- Address Load Tokens Owns Host ID Rack +UN 172.16.39.209 336 KB 256 ? 7c30ea55-7a4f-4d93-86f7-c881772ebe62 b +UN 172.16.25.18 759 KB 256 ? 665dde7e-e420-4db3-8c54-ca71efd39b2e a +UN 172.16.87.27 503 KB 256 ? c19c89cb-e24c-4062-9df4-2aa90ab29a99 c +``` + +## Scylla Manager + +To integrate a multi-datacenter ScyllaDB cluster with Scylla Manager, you must deploy the Scylla Manager in only one datacenter. + +In this example, let's choose the Kubernetes cluster deployed in the first datacenter to host it. +To deploy Scylla Manager, follow the steps described in [Deploying Scylla Manager on a Kubernetes Cluster](../manager.md) +in ScyllaDB Operator documentation. + +In order to define the Scylla Manager tasks, add them to the ScyllaCluster object deployed in the same Kubernetes cluster +in which your Scylla Manager is running. + +Every datacenter (represented by ScyllaCluster CR) is, by default, provisioned with a new, random Scylla Manager Agent auth token. +To use Scylla Manager with multiple datacenter (represented by ScyllaClusters), you have to make sure they all use the same token. + +Extract it from the first datacenter with the below command: +```shell +kubectl --context="${CONTEXT_DC1}" -n=scylla get secrets/scylla-cluster-auth-token --template='{{ index .data "auth-token.yaml" }}' | base64 -d +``` +```console +auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf +``` + +Save the output, replace the token with your own, and patch the secret in the second datacenter with the below command: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla patch secret/scylla-cluster-auth-token--type='json' -p='[{"op": "add", "path": "/stringData", "value": {"auth-token.yaml": "auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf"}}]' +``` + +Execute a rolling restart of the nodes in DC2 to make sure they pick up the new token: +```shell +kubectl --context="${CONTEXT_DC2}" -n=scylla patch scyllacluster/scylla-cluster --type='merge' -p='{"spec": {"forceRedeploymentReason": "sync scylla-manager-agent token ('"$( date )"')"}}' +``` + + +## ScyllaDBMonitoring + +To monitor your cluster, deploy ScyllaDBMonitoring in every datacenter independently. +To deploy ScyllaDB Monitoring, follow the steps described in [Deploy managed monitoring](../monitoring.md#deploy-managed-monitoring) in ScyllaDB Operator documentation. diff --git a/v1.11/_sources/nodeoperations/automatic-cleanup.md.txt b/v1.11/_sources/nodeoperations/automatic-cleanup.md.txt new file mode 100644 index 00000000000..5e0535cca97 --- /dev/null +++ b/v1.11/_sources/nodeoperations/automatic-cleanup.md.txt @@ -0,0 +1,6 @@ +# Automatic cleanup and replacement in case when k8s node is lost + +In case when your k8s cluster loses one of the nodes due to incident or explicit removal, Scylla Pods may become unschedulable due to PVC node affinity. + +When `automaticOrphanedNodeCleanup` flag is enabled in your ScyllaCluster, Scylla Operator will perform automatic +node replacement of a Pod which lost his bound resources. diff --git a/v1.11/_sources/nodeoperations/index.rst.txt b/v1.11/_sources/nodeoperations/index.rst.txt new file mode 100644 index 00000000000..c04919e5d13 --- /dev/null +++ b/v1.11/_sources/nodeoperations/index.rst.txt @@ -0,0 +1,22 @@ +====================================== +Node operations using Scylla Operator +====================================== + +.. toctree:: + :hidden: + :maxdepth: 2 + + scylla-upgrade + replace-node + automatic-cleanup + maintenance-mode + restore + + +Choose a topic: + +* :doc:`Scylla version upgrade ` +* :doc:`Replace Scylla node ` +* :doc:`Automatic cleanup and replacement when k8s node is lost ` +* :doc:`Maintenance mode ` +* :doc:`Restore from backup ` \ No newline at end of file diff --git a/v1.11/_sources/nodeoperations/maintenance-mode.md.txt b/v1.11/_sources/nodeoperations/maintenance-mode.md.txt new file mode 100644 index 00000000000..c976ecc2b87 --- /dev/null +++ b/v1.11/_sources/nodeoperations/maintenance-mode.md.txt @@ -0,0 +1,19 @@ +# Maintenance mode + +When maintenance mode is enabled, readiness probe of Scylla Pod will always return failure and liveness probe will always succeed. This causes that Pod under maintenance +is being removed from K8s Load Balancer and DNS registry but Pod itself stays alive. + +This allows the Scylla Operator to interact with Scylla and Scylla dependencies inside the Pod. +For example user may turn off Scylla process, do something with the filesystem and bring the process back again. + +To enable maintenance mode add `scylla/node-maintenance` label to service in front of Scylla Pod. + +```bash +kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance="" +``` + +To disable, simply remove this label from service. + +```bash +kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance- +``` diff --git a/v1.11/_sources/nodeoperations/replace-node.md.txt b/v1.11/_sources/nodeoperations/replace-node.md.txt new file mode 100644 index 00000000000..3e6a8c7f024 --- /dev/null +++ b/v1.11/_sources/nodeoperations/replace-node.md.txt @@ -0,0 +1,74 @@ +# Replacing a Scylla node + +## Replacing a dead node +In the case of a host failure, it may not be possible to bring back the node to life. + +Replace dead node operation will cause the other nodes in the cluster to stream data to the node that was replaced. +This operation can take some time (depending on the data size and network bandwidth). + +_This procedure is for replacing one dead node. To replace more than one dead node, run the full procedure to completion one node at a time_ + +**Procedure** + +1. Verify the status of the node using `nodetool status` command, the node with status DN is down and need to be replaced + ```bash + kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status + Datacenter: us-east-1 + ===================== + Status=Up/Down + |/ State=Normal/Leaving/Joining/Moving + -- Address Load Tokens Owns Host ID Rack + UN 10.43.125.110 74.63 KB 256 ? 8ebd6114-969c-44af-a978-87a4a6c65c3e us-east-1a + UN 10.43.231.189 91.03 KB 256 ? 35d0cb19-35ef-482b-92a4-b63eee4527e5 us-east-1a + DN 10.43.43.51 74.77 KB 256 ? 1ffa7a82-c41c-4706-8f5f-4d45a39c7003 us-east-1a + ``` +1. Identify service which is bound to down node by checking IP address + ```bash + kubectl -n scylla get svc + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 3h12m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.231.189 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h12m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.125.110 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h11m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.43.51 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h5m + ``` +1. Drain node which we would like to replace using. **This command may delete your data from local disks attached to given node!** + ```bash + kubectl drain gke-scylla-demo-default-pool-b4b390a1-6j12 --ignore-daemonsets --delete-local-data + ``` + + Pod which will be replaced should enter the `Pending` state + ```bash + kubectl -n scylla get pods + NAME READY STATUS RESTARTS AGE + simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 3h21m + simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 3h19m + simple-cluster-us-east-1-us-east-1a-2 0/2 Pending 0 8m14s + ``` +1. To being node replacing, add `scylla/replace=""` label to service bound to pod we are replacing. + ```bash + kubectl -n scylla label svc simple-cluster-us-east-1-us-east-1a-2 scylla/replace="" + ``` + Your failed Pod should be recreated on available k8s node + ```bash + kubectl -n scylla get pods + NAME READY STATUS RESTARTS AGE + simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 3h27m + simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 3h25m + simple-cluster-us-east-1-us-east-1a-2 1/2 Running 0 9s + ``` + Because other nodes in cluster must stream data to new node this operation might take some time depending on how much data your cluster stores. + After bootstraping is over, your new Pod should be ready to go. + Old one shouldn't be no longer visible in `nodetool status` + ```bash + kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status + Datacenter: us-east-1 + ===================== + Status=Up/Down + |/ State=Normal/Leaving/Joining/Moving + -- Address Load Tokens Owns Host ID Rack + UN 10.43.125.110 74.62 KB 256 ? 8ebd6114-969c-44af-a978-87a4a6c65c3e us-east-1a + UN 10.43.231.189 91.03 KB 256 ? 35d0cb19-35ef-482b-92a4-b63eee4527e5 us-east-1a + UN 10.43.191.172 74.77 KB 256 ? 1ffa7a82-c41c-4706-8f5f-4d45a39c7003 us-east-1a + ``` +1. Run the repair on the cluster to make sure that the data is synced with the other nodes in the cluster. + You can use [Scylla Manager](../manager.md) to run the repair. diff --git a/v1.11/_sources/nodeoperations/restore.md.txt b/v1.11/_sources/nodeoperations/restore.md.txt new file mode 100644 index 00000000000..f8ac607d9d6 --- /dev/null +++ b/v1.11/_sources/nodeoperations/restore.md.txt @@ -0,0 +1,217 @@ +# Restore from backup + +This procedure will describe how to restore from backup taken using [Scylla Manager](../manager.md) to a fresh **empty** cluster of any size. + +:::{caution} +Due to a [bug](https://github.com/scylladb/scylla-manager/issues/3679) in Scylla Manager not supporting ScyllaClusters having both non-TLS and TLS CQL ports open, you have to disable the TLS certificate management +in Scylla Operator. +This step will no longer be required, when the bug is fixed. + +To disable TLS certificate management in Scylla Operator add `--feature-gates="AutomaticTLSCertificates=false"` flag to Scylla Operator deployment. + +```console +kubectl -n scylla-operator patch deployment/scylla-operator --type=json -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--feature-gates=AutomaticTLSCertificates=false"}]' +``` + +::: + +In the following example, the ScyllaCluster, which was used to take the backup, is called `source`. Backup will be restored into the ScyllaCluster named `target`. + +::::{tab-set} +:::{tab-item} Source ScyllaCluster +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: source + namespace: scylla +spec: + agentVersion: 3.2.5 + version: 5.4.1 + developerMode: true + backups: + - name: foo + location: + - s3:source-backup + keyspace: + - '*' + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 1 + storage: + capacity: 1Gi + resources: + limits: + cpu: 1 + memory: 1Gi +``` +::: +:::{tab-item} Target ScyllaCluster +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: target + namespace: scylla +spec: + agentVersion: 3.2.5 + version: 5.4.1 + developerMode: true + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 1 + storage: + capacity: 1Gi + resources: + limits: + cpu: 1 + memory: 1Gi +``` +::: +:::: + +Make sure your target cluster is already registered in Scylla Manager. To get a list of all registered clusters, execute the following command: +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool cluster list ++--------------------------------------+---------------------------------------+---------+-----------------+ +| ID | Name | Port | CQL credentials | ++--------------------------------------+---------------------------------------+---------+-----------------+ +| af1dd5cd-0406-4974-949f-dc9842980080 | scylla/target | default | set | +| ebd82268-efb7-407e-a540-3619ae053778 | scylla/source | default | set | ++--------------------------------------+---------------------------------------+---------+-----------------+ +``` + +Identify the tag of a snapshot which you want to restore. To get a list of all available snapshots, execute following command: +```console +kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c --all-clusters -L +``` + +Where: +* `CLUSTER_ID` - the name or ID of a registered cluster with access to `BACKUP_LOCATION`. +* `BACKUP_LOCATION` - the location in which the backup is stored. + +In this example, `BACKUP_LOCATION` is `s3:source-backup`. Use the name of cluster which has access to the backup location for `CLUSTER_ID`. +In this example, it's `scylla/target`. + +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c scylla/target --all-clusters -L s3:source-backup +backup/ff36d7e0-af2e-458c-afe6-868e0f3396b2 +Snapshots: + - sm_20240105115931UTC (409MiB, 1 nodes) +Keyspaces: + - system_schema (15 tables) + - users (9 tables) + +``` + +In the below commands, we are restoring the `sm_20240105115931UTC` snapshot. Replace it with a tag of a snapshot that you want to restore. +Restoring consist of two steps. First, you'll restore the schema, and then the data. +To restore schema, create a restore task manually on target ScyllaCluster by executing following command: +```console +kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c -L -T --restore-schema +``` + +Where: +* `CLUSTER_ID` - a name or ID of a cluster you want to restore into. +* `BACKUP_LOCATION` - the location in which the backup is stored. +* `SNAPSHOT_TAG` - a tag of a snapshot that you want to restore. + +When the task is created, the command will output the ID of a restore task. +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-schema +restore/57228c52-7cf6-4271-8c8d-d446ff160747 +``` + +Use the following command to check progress of the restore task: +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/57228c52-7cf6-4271-8c8d-d446ff160747 +Restore progress +Run: 0dd20cdf-abc4-11ee-951c-6e7993cf42ed +Status: DONE - restart required (see restore docs) +Start time: 05 Jan 24 12:15:02 UTC +End time: 05 Jan 24 12:15:09 UTC +Duration: 6s +Progress: 100% | 100% +Snapshot Tag: sm_20240105115931UTC + ++---------------+-------------+----------+----------+------------+--------+ +| Keyspace | Progress | Size | Success | Downloaded | Failed | ++---------------+-------------+----------+----------+------------+--------+ +| system_schema | 100% | 100% | 214.150k | 214.150k | 214.150k | 0 | ++---------------+-------------+----------+----------+------------+--------+ +``` + +As suggested in the progress output, you will need to execute a rolling restart of the ScyllaCluster. +```console +kubectl patch scyllacluster target --type merge -p '{"spec": {"forceRedeploymentReason": "schema restored"}}' +``` + +Use the following commands to wait until restart is finished: +```console +$ kubectl wait --for='condition=Progressing=False' -n scylla scyllaclusters.scylla.scylladb.com/target +scyllacluster.scylla.scylladb.com/target condition met + +$ kubectl wait --for='condition=Degraded=False' -n scylla scyllaclusters.scylla.scylladb.com/target +scyllacluster.scylla.scylladb.com/target condition met + +$ kubectl wait --for='condition=Available=True' -n scylla scyllaclusters.scylla.scylladb.com/target +scyllacluster.scylla.scylladb.com/target condition met +``` + +To restore the tables content, create a restore task manually on target ScyllaCluster by executing the following command: +```console +kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c -L -T --restore-tables +``` + +Where: +* `CLUSTER_ID` - a name or ID of a cluster you want to restore into. +* `BACKUP_LOCATION` - the location in which the backup is stored. +* `SNAPSHOT_TAG` - a tag of a snapshot that you want to restore. + +When the task is created, the command will output the ID of a restore task. +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-tables +restore/63642069-bed5-4def-ba0f-68c49e47ace1 +``` + +Use the following command to check progress of the restore task: +```console +$ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/63642069-bed5-4def-ba0f-68c49e47ace1 +Restore progress +Run: ab015cef-abc8-11ee-9521-6e7993cf42ed +Status: DONE +Start time: 05 Jan 24 12:48:04 UTC +End time: 05 Jan 24 12:48:15 UTC +Duration: 11s +Progress: 100% | 100% +Snapshot Tag: sm_20240105115931UTC + ++-------------+-------------+--------+---------+------------+--------+ +| Keyspace | Progress | Size | Success | Downloaded | Failed | ++-------------+-------------+--------+---------+------------+--------+ +| users | 100% | 100% | 409MiB | 409MiB | 409MiB | 0 | ++-------------+-------------+--------+---------+------------+--------+ + +Post-restore repair progress +Run: ab015cef-abc8-11ee-9521-6e7993cf42ed +Status: DONE +Start time: 05 Jan 24 12:48:04 UTC +End time: 05 Jan 24 12:48:15 UTC +Duration: 11s +Progress: 100% +Intensity: 1 +Parallel: 0 +Datacenters: + - us-east-1 + ++-------------+--------------+----------+----------+ +| Keyspace | Table | Progress | Duration | ++-------------+--------------+----------+----------+ +| users | users | 100% | 0s | ++-------------+--------------+----------+----------+ + +``` diff --git a/v1.11/_sources/nodeoperations/scylla-upgrade.md.txt b/v1.11/_sources/nodeoperations/scylla-upgrade.md.txt new file mode 100644 index 00000000000..d39c9666c5e --- /dev/null +++ b/v1.11/_sources/nodeoperations/scylla-upgrade.md.txt @@ -0,0 +1,102 @@ +# Upgrading version of Scylla + +To upgrade Scylla version using Operator user have to modify existing ScyllaCluster definition. + +In this example cluster will be upgraded to version `4.4.5`. +```bash +kubectl -n scylla patch ScyllaCluster simple-cluster -p '{"spec":{"version": "4.4.5"}}' --type=merge +``` + +Operator supports two types of version upgrades: +1. Patch upgrade +1. Generic upgrade + + +**Patch upgrade** + +Patch upgrade is executed when only patch version change is detected according to [semantic versioning format](https://semver.org/). +Procedure simply rolls out a restart of whole cluster and upgrades Scylla container image for each node one by one. + +Example: `4.0.0 -> 4.0.1` + +**Generic upgrade** + +Generic upgrades are executed for the non patch version changes. + +Example: `4.0.0 -> 2020.1.0` or `4.0.0 -> 4.1.0` or even `4.0.0 -> nightly` + +User can observe current state of upgrade in ScyllaCluster status. +```bash +kubectl -n scylla describe ScyllaCluster simple-cluster +[...] +Status: + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.1.9 + Upgrade: + Current Node: simple-cluster-us-east-1-us-east-1a-2 + Current Rack: us-east-1a + Data Snapshot Tag: so_data_20201228135002UTC + From Version: 4.1.9 + State: validate_upgrade + System Snapshot Tag: so_system_20201228135002UTC + To Version: 4.2.2 +``` + +Each upgrade begins with taking a snapshot of `system` and `system_schema` keyspaces on all nodes in parallel. +Name of this snapshot tag is saved in upgrade status under `System Snapshot Tag`. + +Before nodes in rack are upgraded, underlying StatefulSet is changed to use `OnDelete` UpgradeStrategy. +This allows Operator have a full control over when Pod image is changed. + +When a node is being upgraded, [maintenance mode](#maintenance-mode) is enabled, then the node is drained and snapshot of all data keyspaces is taken. +Snapshot tag is saved under `Data Snapshot Tag` and is the same for all nodes during the procedure. +Once everything is set up, maintenance mode is disabled and Scylla Pod is deleted. Underlying StatefulSet will bring up a new +Pod with upgraded version. +Once Pod will become ready, data snapshot from this particular node is removed, and Operator moves to next node. + +Once every rack is upgraded, system snapshot is removed from all nodes in parallel and previous StatefulSet UpgradeStrategy is restored. +At this point, all your nodes should be already in desired version. + +Current state of upgrade can be traced using `Current Node`, `Current Rack` and `State` status fields. +* `Current Node` shows which node is being upgraded. +* `Current Rack` displays which rack is being upgraded. +* `State` contain information at which stage upgrade is. + +`State` can have following values: +* `begin_upgrade` - upgrade is starting +* `check_schema_agreement` - Operator waits until all nodes reach schema agreement. It waits for it for 1 minute, prints an error log message and check is retried. +* `create_system_backup` - system keyspaces snapshot is being taken +* `find_next_rack` - Operator finds out which rack must be upgraded next, decision is saved in `Current Rack` +* `upgrade_image_in_pod_spec` - Image and UpgradeStrategy is upgraded in underlying StatefulSet +* `find_next_node` - Operator finds out which node must be upgraded next, decision is saved in `Current Node` +* `enable_maintenance_mode` - maintenance mode is being enabled +* `drain_node` - node is being drained +* `backup_data` - snapshot of data keyspaces is being taken +* `disable_maintenance_mode` - maintenance mode is being disabled +* `delete_pod` - Scylla Pod is being deleted +* `validate_upgrade` - Operator validates if new pod enters Ready state and if Scylla version is upgraded +* `clear_data_backup` - snapshot of data keyspaces is being removed +* `clear_system_backup` - snapshot of system keyspaces is being removed +* `restore_upgrade_strategy` - restore UpgradeStrategy in underlying StatefulSet +* `finish_upgrade` - upgrade cleanup + +**Recovering from upgrade failure** + +Upgrade may get stuck on `validate_upgrade` stage. This happens when Scylla Pod refuses to properly boot up. + +To continue with upgrade, first turn off operator by scaling Operator replicas to zero: +```bash +kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=0 +``` +Then user have to manually resolve issue with Scylla by checking what is the root cause of a failure in Scylla container logs. +If needed data and system keyspaces SSTable snapshots are available on the node. You can check ScyllaCluster status for their names. + +Once issue is resolved and Scylla Pod is up and running (Pod is in Ready state), scale Operator back to two replicas: +```bash +kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=2 +``` + +Operator should continue upgrade process from where it left off. diff --git a/v1.11/_sources/performance.md.txt b/v1.11/_sources/performance.md.txt new file mode 100644 index 00000000000..4b0bbd96781 --- /dev/null +++ b/v1.11/_sources/performance.md.txt @@ -0,0 +1,95 @@ +# Performance tuning + +Scylla Operator 1.6 introduces a new experimental feature allowing users to optimize Kubernetes nodes. + +## Node tuning + +Starting from Operator 1.6, a new CRD called NodeConfig is available, allowing users to target Nodes which should be tuned. +When a Node is supposed to be optimized, the Scylla Operator creates a DaemonSet covering these Nodes. +Nodes matching the provided placement conditions will be subject to tuning. + +Below example NodeConfig tunes nodes having `scylla.scylladb.com/node-type=scylla` label: +``` +apiVersion: scylla.scylladb.com/v1alpha1 +kind: NodeConfig +metadata: + name: cluster +spec: + placement: + nodeSelector: + scylla.scylladb.com/node-type: scylla +``` +For more details about new CRD use: +``` +kubectl explain nodeconfigs.scylla.scylladb.com/v1alpha1 +``` + +For all optimizations we use a Python script available in the Scylla image called perftune. +Perftune executes the performance optmizations like tuning the kernel, network, disk devices, spreading IRQs across CPUs and more. + +Tuning consists of two separate optimizations: common node tuning, and tuning based on Scylla Pods and their resource assignment. +Node tuning is executed immediately. Pod tuning is executed when Scylla Pod lands on the same Node. + +Scylla works most efficently when it's pinned to CPU and not interrupted. +One of the most common causes of context-switching are network interrupts. Packets coming to a node need to be processed, +and this requires CPU shares. + +On K8s we always have at least a couple of processes running on the node: kubelet, kubernetes provider applications, daemons etc. +These processes require CPU shares, so we cannot dedicate entire node processing power to Scylla, we need to leave space for others. +We take advantage of it, and we pin IRQs to CPUs not used by any Scylla Pods exclusively. + +Tuning resources are created in a special namespace called `scylla-operator-node-tuning`. + +The tuning is applied only to pods with `Guaranteed` QoS class. Please double check your ScyllaCluster resource specification +to see if it meets all conditions. + +## Kubernetes tuning + +By default, the kubelet uses the CFS quota to enforce pod CPU limits. +When the node runs many CPU-bound pods, the workload can move around different CPU cores depending on whether the pod +is throttled and which CPU cores are available. +However, kubelet may be configured to assign CPUs exclusively, by setting the CPU manager policy to static. + +Setting up kubelet configuration is provider specific. Please check the docs for your distribution or talk to your +provider. + +Only pods within the [Guaranteed QoS class](https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed)) can take advantage of this option. +When such pod lands on a Node, kubelet will pin them to specific CPUs, and those won't be part of the shared pool. + +In our case there are two requirements each ScyllaCluster must fulfill to receive a Guaranteed QoS class: +* resource request and limits must be equal or only limits have to be provided +* agentResources must be provided and their requests and limits must be equal, or only limits have to be provided + +An example of such a ScyllaCluster that receives a Guaranteed QoS class is below: + +``` +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: guaranteed-cluster + namespace: scylla +spec: + version: 4.5.1 + agentVersion: 2.5.2 + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 3 + storage: + capacity: 500Gi + agentResources: + requests: + cpu: 1 + memory: 1G + limits: + cpu: 1 + memory: 1G + resources: + requests: + cpu: 4 + memory: 16G + limits: + cpu: 4 + memory: 16G +``` \ No newline at end of file diff --git a/v1.11/_sources/releases.md.txt b/v1.11/_sources/releases.md.txt new file mode 100644 index 00000000000..ce4fa27b65d --- /dev/null +++ b/v1.11/_sources/releases.md.txt @@ -0,0 +1,59 @@ +# Releases + +## Schedule +We are aiming to ship a new release approximately every 6 weeks. The following release schedule is only advisory, there are no commitments made to hitting these dates. + +| Release | Code freeze | General availability | +|:-------:|:-----------:|:--------------------:| +| 1.11 | 2023-10-02 | 2023-10-16 | + +## Supported releases +We support the latest 2 releases of the operator to give everyone time to upgrade. + +| Release | General availability | Support ends | +|:-------:|:--------------------:|:---------------:| +| 1.10 | 2023-08-25 | Release of 1.12 | +| 1.9 | 2023-07-04 | Release of 1.11 | +| 1.8 | 2023-01-25 | 2023-08-25 | +| 1.7 | 2022-01-27 | 2023-07-04 | +| 1.6 | 2021-12-03 | 2023-01-25 | +| 1.5 | 2021-09-16 | 2022-01-27 | +| 1.4 | 2021-08-10 | 2021-12-03 | +| 1.3 | 2021-06-17 | 2021-09-16 | +| 1.2 | 2021-05-06 | 2021-08-10 | +| 1.1 | 2021-03-22 | 2021-06-17 | +| 1.0 | 2021-01-21 | 2021-05-06 | + +### Backport policy +Usually, only important bug fixes are eligible for being backported. +This may depend on the situation and assessment of the maintainers. + +## CI/CD +We use [GitHub actions](https://github.com/scylladb/scylla-operator/actions/workflows/go.yaml?query=branch%3Amaster+event%3Apush) for our CI/CD. Every merge to a supported branch, or a creation of a tag will automatically trigger a job to build, test and publish the container image and other artifacts like helm charts. Before we publish any image, it must pass the e2e suite. + +### Automated promotions + +| Git reference | Type | Container image | +| :----------------: | :----: | :--------------------------------------------------: | +| **master** | branch | docker.io/scylladb/scylla-operator:**latest** | +| **vX.Y** | branch | docker.io/scylladb/scylla-operator:**X.Y** | +| **vX.Y.Z** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z** | +| **vX.Y.Z-alpha.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-alpha.N** | +| **vX.Y.Z-beta.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-beta.N** | +| **vX.Y.Z-rc.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-rc.N** | + +### Generally available +GA images aren't build from scratch but rather promoted from an existing release candidates. When we decide a release candidate has the acceptable quality and QA sings it off, the release candidate is promoted to become the GA release. This makes sure the image has exactly the same content and SHA as the tested release candidate. + +## Support matrix + +Support matrix table shows the version requirements for a particular **scylla-operator** version. Be sure to match these requirements, otherwise some functionality will not work. + +| | v1.10 | v1.9 | v1.8 | v1.7 | v1.6 | v1.5 | v1.4 | v1.3 | v1.2 | v1.1 | v1.0 | +|:-----------------:|:----------:|:----------:|:----------:|:-----------------:|:--------------------:|:-----------:|:-----------:|:----------:|:----------:|:----------:|:----------:| +| Kubernetes | `>=1.21` | `>=1.21` | `>=1.21` | `>=1.20 && <1.25` | `>=1.19.10 && <1.25` | `>=1.19.10` | `>=1.19.10` | `>=1.19` | `>=1.19` | `>=1.11` | `>=1.11` | +| CRI API | `v1` | `v1` | `v1alpha2` | `v1alpha2` | `v1alpha2` | | | | | | | +| Scylla OS | `>=5.0` | `>=5.0` | `>=5.0` | `>=4.3` | `>=4.3` | `>=4.3` | `>=4.3` | `>=4.2` | `>=4.2` | `>=4.0` | `>=4.0` | +| Scylla Enterprise | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2020.1` | `>=2020.1` | `>=2020.1` | `>=2020.1` | +| Scylla Manager | `>=2.6` | `>=2.6` | `>=2.6` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | +| Scylla Monitoring | `>=4.0` | `>=4.0` | `>=4.0` | `>=3.0` | `>=3.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | diff --git a/v1.11/_sources/scylla-cluster-crd.md.txt b/v1.11/_sources/scylla-cluster-crd.md.txt new file mode 100644 index 00000000000..75d34f1a028 --- /dev/null +++ b/v1.11/_sources/scylla-cluster-crd.md.txt @@ -0,0 +1,188 @@ +# Scylla Cluster CRD + +Scylla database clusters can be created and configured using the `clusters.scylla.scylladb.com` custom resource definition (CRD). + +Please refer to the the [user guide walk-through](generic.md) for deployment instructions. +This page will explain all the available configuration options on the Scylla CRD. + +## Sample + +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: simple-cluster + namespace: scylla +spec: + version: 2.3.1 + repository: scylladb/scylla + developerMode: true + cpuset: false + automaticOrphanedNodeCleanup: true + repairs: + - name: "weekly us-east-1 repair" + intensity: "2" + interval: "7d" + dc: ["us-east-1"] + backups: + - name: "daily users backup" + rateLimit: ["50"] + location: ["s3:cluster-backups"] + interval: "1d" + keyspace: ["users"] + - name: "weekly full cluster backup" + rateLimit: ["50"] + location: ["s3:cluster-backups"] + interval: "7d" + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 3 + storage: + capacity: 500G + storageClassName: local-raid-disks + resources: + requests: + cpu: 8 + memory: 32Gi + limits: + cpu: 8 + memory: 32Gi + placement: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: failure-domain.beta.kubernetes.io/region + operator: In + values: + - us-east-1 + - key: failure-domain.beta.kubernetes.io/zone + operator: In + values: + - us-east-1a + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule +``` + +## Settings Explanation + +### Cluster Settings + +* `version`: The version of Scylla to use. It is used as the image tag to pull. +* `agentVersion`: The version of Scylla Manager Agent to use. It is used as the image tag to pull. +* `repository`: Optional field. Specifies a custom image repo. If left unset, the official docker hub repo is used (scylladb/scylla). +* `agentRepository`: Optional field. Specifies a custom Scylla Manager Agent image repo. If left unset, the official docker hub repo is used (scylladb/scylla). +* `developerMode`: Optional field. If it's true, then Scylla is started in [developer mode](https://www.scylladb.com/2016/09/13/test-dev-env/). This setting is for shared test/dev environments. +* `cpuset`: Optional field. If it's true, then the operator will start Scylla with cpu pinning for maximum performance. For this to work, you need to set the kubelet to use the [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and only specify limits in resources. +* `automaticOrphanedNodeCleanup`: Optional field. Controls if automatic orphan node cleanup should be performed. +* `alternator`: Optional field. Defines Alternator configuration. + * `port`: Port on which to bind to Alternator API. + * `writeIsolation`: *required* Desired write isolation. +* `genericUpgrade`: Optional field. Defines GenericUpgrade configuration. + * `failureStrategy`: specifies which logic is executed when upgrade failure happens. Currently only `Retry` is supported. + * `pollInterval`: specifies how often upgrade logic polls on state updates. + Increasing this value should lower number of requests sent to the kube-apiserver, but it may affect + overall time spent during upgrade. +* `datacenter`: Datacenter definition. +* `sysctls`: Optional field. Sysctl properties to be applied during initialization. +* `scyllaArgs`: Optional field. Command line argument passed to Scylla container image. Note: not all Scylla versions support it. +* `network`: Optional field. Allows to customize network parameters. + * `hostNetworking`: controls if host networking should be enabled. + * `dnsPolicy`: controls Scylla Pod DNS Policy. See [details](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy). +* `repairs`: Optional field. Repair tasks definitions. See `Scylla Manager settings` for details. +* `backups`: Optional field. Repair tasks definitions. See `Scylla Manager settings` for details. + + +In the Scylla model, each cluster contains datacenters and each datacenter contains racks. At the moment, the operator only supports single datacenter setups. + +### Scylla Manager settings + +Tasks are scheduled only when Scylla Manager is deployed in K8s cluster. + +Repairs: +* `name` - **required** - human readable name of the task. It must be unique across all tasks. +* `startDate` - specifies the task start date expressed in the RFC3339 format or `now[+duration]`, e.g. `now+3d2h10m`, +valid units are d, h, m, s (default "now"). +* `interval` - Optional field. Task schedule interval e.g. `3d2h10m`, valid units are d, h, m, s (default "0"). +* `numRetries` - Optional field. The number of times a scheduled task will retry to run before failing (default 3). +* `dc` - Optional field. A list of datacenter glob patterns, e.g. `["dc1", "!otherdc*"]` used to specify the DCs to include or exclude from backup. +* `failFast` - Optional field. Stop repair on first error. +* `intensity` - Optional field. Specifies how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. + If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). + Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. + Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. + For Scylla clusters that **do not support row-level repair**, intensity can be a decimal between (0,1). + In that case it specifies percent of shards that can be repaired in parallel on a repair master node. + For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1. + **Intensity is a number passed as string due to lack of support for float values in k8s controller runtime** +* `parallel` - Optional field. Specifies the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). + Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. + The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. + The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2. +* `keyspace` - Optional field. A list of keyspace/tables glob patterns, e.g. `["keyspace", "!keyspace.table_prefix_*"]` +used to include or exclude keyspaces from repair. +* `smallTableThreshold` - Optional field. Enable small table optimization for tables of size lower than given threshold. +Supported units `[B, MiB, GiB, TiB]` (default `"1GiB"`). + +Backups: + +* `name` - **required** - human readable name of the task. It must be unique across all tasks. +* `startDate` - Optional field. Specifies the task start date expressed in the RFC3339 format or `now[+duration]`, e.g. `now+3d2h10m`, +valid units are d, h, m, s (default "now"). +* `interval` - Optional field. task schedule interval e.g. `3d2h10m`, valid units are d, h, m, s (default "0"). +* `numRetries` - Optional field. the number of times a scheduled task will retry to run before failing (default 3). +* `dc` - Optional field. A list of datacenter glob patterns, e.g. `["dc1","!otherdc*"]` used to specify the DCs to include or exclude from backup. +* `keyspace` - Optional field. A list of keyspace/tables glob patterns, e.g. `["keyspace","!keyspace.table_prefix_*"]` used to include or exclude keyspaces from backup. +* `location` - Optional field. A list of backup locations in the format `[:]:` ex. `s3:my-bucket`. +The `:` part is optional and is only needed when different datacenters are being used to upload data to different locations. +`` Optional field. must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. +The only supported storage at the moment are `s3` and `gcs`. +* `rateLimit` - Optional field. A list of megabytes (MiB) per second rate limits expressed in the format `[:]`. +The `:` part is optional and only needed when different datacenters need different upload limits. +Set to 0 for no limit (default 100). +* `retention` - Optional field. The number of backups which are to be stored (default 3). +* `snapshotParallel` - Optional field. A list of snapshot parallelism limits in the format `[:]`. +The `:` part is optional and allows for specifying different limits in selected datacenters. +If The `:` part is not set, the limit is global (e.g. `["dc1:2,5"]`) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters. +* `uploadParallel` - Optional field. A list of upload parallelism limits in the format `[:]`. +The `:` part is optional and allows for specifying different limits in selected datacenters. +If The `:` part is not set the limit is global (e.g. `["dc1:2,5"]`) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters. + + +### Datacenter Settings + +* `name`: Name of the datacenter. Usually, a datacenter corresponds to a region. +* `racks`: List of racks for the specific datacenter. + +### Rack Settings + +* `name`: Name of the rack. Usually, a rack corresponds to an availability zone. +* `members`: Number of Scylla members for the specific rack. (In Scylla documentation, they are called nodes. We don't call them nodes to avoid confusion as a Scylla Node corresponds to a Kubernetes Pod, not a Kubernetes Node). +* `storage`: Defines the specs of the underlying storage. + * `capacity`: Capacity of the PersistentVolume to request. + * `storageClassName`: Optional field. [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) of PersistentVolume to request. +* `resources`: Defines the CPU and RAM resources for the Scylla Pods. + * `requests`: The minimum amount of resources needed to run a Scylla container. + * `cpu`: CPU requests. + * `memory`: RAM requests. + * `limits`: The maximum amount of resources that can be used by a Scylla container. + * `cpu`: CPU limits. + * `memory`: RAM limits. +* `agentResources`: Optional field. Defines the CPU and RAM resources for the Scylla Manager Agent container. See `resources` for details. +* `volumes`: Optional field. Defines volumes available in Scylla Pod. See [details](https://kubernetes.io/docs/concepts/storage/volumes/). +* `volumeMounts`: Optional field. Defines which volumes will be attached to Scylla container. +* `agentVolumeMounts`: Optional field. Defines which volumes will be attached to Agent container. +* `scyllaConfig`: Optional field. name of custom config map which will be merged with Scylla config. +* `scyllaAgentConfig`: Optional field. name of custom secret which will be merged with Scylla Manager Agent config. +* `placement`: Optional field. Defines the placement of Scylla Pods. Has the following subfields: + * [`nodeAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature) + * [`podAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature) + * [`podAntiAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature) + * [`tolerations`](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration) diff --git a/v1.11/_sources/support/index.rst.txt b/v1.11/_sources/support/index.rst.txt new file mode 100644 index 00000000000..9c623218acb --- /dev/null +++ b/v1.11/_sources/support/index.rst.txt @@ -0,0 +1,12 @@ +========================================================== +Support +========================================================== + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + overview + known-issues + troubleshooting/index + must-gather diff --git a/v1.11/_sources/support/known-issues.md.txt b/v1.11/_sources/support/known-issues.md.txt new file mode 100644 index 00000000000..1af3a7bfdd1 --- /dev/null +++ b/v1.11/_sources/support/known-issues.md.txt @@ -0,0 +1,14 @@ +# Known issues + +### Scylla Manager does not boot up on Minikube + +If your Scylla Manager is failing to apply 8th migration (008_*), then apply fix for [TRUNCATE queries](#truncate-queries-does-not-work-on-minikube). + +### TRUNCATE queries does not work on Minikube + +The `TRUNCATE` queries requires [hairpinning](https://en.wikipedia.org/wiki/Hairpinning) to be enabled. On minikube this is disabled by default. + +To fix it execute the following command: +``` +minikube ssh sudo ip link set docker0 promisc on +``` diff --git a/v1.11/_sources/support/must-gather.md.txt b/v1.11/_sources/support/must-gather.md.txt new file mode 100644 index 00000000000..7e0089084da --- /dev/null +++ b/v1.11/_sources/support/must-gather.md.txt @@ -0,0 +1,101 @@ +# Gathering data with must-gather + +`must-gather` is an embedded tool in Scylla Operator that helps collecting all the necessary info when something goes wrong. + +The tool talks to the Kubernetes API, retrieves a predefined set of resources and saves them into a folder in your current directory. +By default, all collected Secrets are censored to avoid sending sensitive data. +That said, you can always review the archive before you attach it to an issue or your support request. + +Given it needs to talk to the Kubernetes API, at the very least, you need to supply the `--kubeconfig` flag with a path to the kubeconfig file for your Kubernetes cluster, or set the `KUBECONFIG` environment variable. + +## Running must-gather + +There is more than one way to run `must-gather`. +Here are some examples of how you can run the tool. + +### Prerequisites + +All examples assume you have exported `KUBECONFIG` environment variable that points to a kubeconfig file on your machine. +If not, you can run this command to export the common default location. +Please make sure such a file exists. + +```bash +export KUBECONFIG=~/.kube/config +ls -l "${KUBECONFIG}" +``` + +:::{note} + There can be slight deviations in the arguments for your container tool, depending on the container runtime, whether you use SELinux or similar factors. + + As an example, the need for the `Z` option on volume mounts depends on whether you use SELinux and what context is applied on your file or directory. + If you get an error mentioning `Error: lsetxattr : operation not supported`, try it without the `Z` option. +::: + +Let's also check whether your kubeconfig uses [external authentication plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins). +You can determine that by running +```bash +kubectl config view --minify +``` +and checking whether it uses an external exec plugin by looking for this pattern (containing the `exec` key) +```yaml +users: +- name: + user: + exec: +``` +If not, you can skip the rest of this section. + +In case your kubeconfig depends on external binaries, you have to take a few extra steps because the external binary won't be available within our container to authenticate the requests. + +Similarly to how Pods are run within Kubernetes, we'll create a dedicated ServiceAccount for must-gather and use it to run the tool. +(When you are done using it, feel free to remove the Kubernetes resources created for that purpose.) + +```bash +kubectl create namespace must-gather +kubectl -n must-gather create serviceaccount must-gather +kubectl create clusterrolebinding must-gather --clusterrole=cluster-admin --serviceaccount=must-gather:must-gather +export MUST_GATHER_TOKEN +MUST_GATHER_TOKEN=$( kubectl -n must-gather create token must-gather --duration=1h ) +kubeconfig=$( mktemp ) +# Create a copy of the existing kubeconfig and +# replace user authentication using yq, or by adjusting the fields manually. +kubectl config view --minify --raw -o yaml | yq -e '.users[0].user = {"token": env(MUST_GATHER_TOKEN)}' > "${kubeconfig}" +KUBECONFIG="${kubeconfig}" +``` + +:::{note} + If you don't have `yq` installed, you can get it at https://github.com/mikefarah/yq/#install or you can replace the user authentication settings manually. +::: + +### Podman +```bash +podman run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro,Z" -v="$( pwd ):/workspace:Z" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig +``` + +### Docker +```bash +docker run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro" -v="$( pwd ):/workspace" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig +``` + +## Limiting must-gather to a particular namespace + +If you are running a large Kubernetes cluster with many ScyllaClusters, it may be useful to limit the collection of ScyllaClusters to a particular namespace. +Unless you hit scale issues, we advise not to use this mode, as sometimes the ScyllaClusters affect other collected resources, like the manager or they form a multi-datacenter. + +```bash +scylla-operator must-gather --namespace="" +``` + +:::{note} + The `--namespace` flag affects only `ScyllaClusters`. + Other resources related to the operator installation or cluster state will still be collected from other namespaces. +::: + +### Collecting every resource in the cluster + +By default, `must-gather` collects only a predefined subset of resources. +You can also request collecting every resource in the Kubernetes API, if the default set wouldn't be enough to debug an issue. + +```bash +scylla-operator must-gather --all-resources +``` diff --git a/v1.11/_sources/support/overview.md.txt b/v1.11/_sources/support/overview.md.txt new file mode 100644 index 00000000000..7097438589c --- /dev/null +++ b/v1.11/_sources/support/overview.md.txt @@ -0,0 +1,14 @@ +# Support overview + +## Get support + +ScyllaDB provides administrators with [paid support](https://www.scylladb.com/product/support/#enterprise-support), including Scylla Operator. + +## Troubleshooting issues + +To learn more about what to do when issues arise, visit our dedicated [troubleshooting section](troubleshooting/index). + +## Gather data about your cluster + +Scylla Operator contains an embedded tool called [must-gather](must-gather.md) that can collect the required information for requesting support or reporting issues. +Support requests and bug reports are required to attach the must-gather archive to help us understand the issue. diff --git a/v1.11/_sources/support/troubleshooting/index.rst.txt b/v1.11/_sources/support/troubleshooting/index.rst.txt new file mode 100644 index 00000000000..b83118e6b18 --- /dev/null +++ b/v1.11/_sources/support/troubleshooting/index.rst.txt @@ -0,0 +1,8 @@ +========================================================== +Troubleshooting +========================================================== + +.. toctree:: + :maxdepth: 2 + + installation diff --git a/v1.11/_sources/support/troubleshooting/installation.md.txt b/v1.11/_sources/support/troubleshooting/installation.md.txt new file mode 100644 index 00000000000..b93fcce7b51 --- /dev/null +++ b/v1.11/_sources/support/troubleshooting/installation.md.txt @@ -0,0 +1,34 @@ +# Troubleshooting installation issues + +## Webhooks +Scylla Operator provides several custom API resources that use webhooks to function properly. + +Unfortunately, it is often the case that user's clusters have modified SDN, that doesn't extend to the control plane, and Kubernetes apiserver is not able to reach the pods that serve the webhook traffic. +Another common case are firewall rules that block the webhook traffic. + +:::{note} + To be called a Kubernetes cluster, clusters are required to pass Kubernetes conformance test suite. + This suite includes tests that require Kubernetes apiserver to be able to reach webhook services. +::: + +:::{note} + Before filing an issue, please make sure your cluster webhook traffic can reach your webhook services, independently of Scylla Operator resources. +::: + +### EKS + +#### Custom CNI +EKS is currently breaking Kubernetes webhooks [when used with custom CNI networking](https://github.com/aws/containers-roadmap/issues/1215). + +:::{note} + We advise you to avoid using such setups and use a conformant Kubernetes cluster that supports webhooks. +::: + +There are some workarounds where you can reconfigure the webhook to use Ingress or hostNetwork instead, but it's beyond a standard configuration that we support and not specific to the Scylla Operator. + +### GKE + +#### Private clusters + +If you use GKE private clusters you need to manually configure the firewall to allow webhook traffic. +You can find more information on how to do that in [GKE private clusters docs](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#add_firewall_rules). diff --git a/v1.11/_sources/upgrade.md.txt b/v1.11/_sources/upgrade.md.txt new file mode 100644 index 00000000000..ab14157256b --- /dev/null +++ b/v1.11/_sources/upgrade.md.txt @@ -0,0 +1,184 @@ +# Upgrade of Scylla Operator + +This page describes Scylla Operator upgrade procedures. +There are two generic update procedures - via Helm and via kubectl. Before upgrading, please check this page to find out +if your target version requires additional upgrade steps. + +## Upgrade via Helm + +Helm doesn't support managing CustomResourceDefinition resources ([#5871](https://github.com/helm/helm/issues/5871), [#7735](https://github.com/helm/helm/issues/7735)) +These are only created on first install and never updated. In order to update them, users have to do it manually. + +Replace `` with the name of your Helm release for Scylla Operator and replace `` with the version number you want to install: +1. Make sure Helm chart repository is up-to-date: + ``` + helm repo add scylla-operator https://storage.googleapis.com/scylla-operator-charts/stable + helm repo update + ``` +2. Update CRD resources. We recommend using `--server-side` flag for `kubectl apply`, if your version supports it. + ``` + tmpdir=$( mktemp -d ) \ + && helm pull scylla-operator/scylla-operator --version --untar --untardir "${tmpdir}" \ + && find "${tmpdir}"/scylla-operator/crds/ -name '*.yaml' -printf '-f=%p ' \ + | xargs kubectl apply + ``` +3. Update Scylla Operator + ``` + helm upgrade --version scylla-operator/scylla-operator + ``` + +## Upgrade via kubectl + +Replace `` with the version number you want to install: + +1. Checkout source code of version you want to use: + ``` + git checkout + ``` +2. Manifests use rolling minor version tag, you may want to pin it to specific version: + ``` + find deploy/operator -name "*.yaml" | xargs sed --follow-symlinks -i -E "s^docker.io/scylladb/scylla-operator:[0-9]+\.[0-9]+^docker.io/scylladb/scylla-operator:^g" + ``` +3. Update Scylla Operator. We recommend using `--server-side` flag for `kubectl apply`, if your version supports it. + ``` + kubectl apply -f deploy/operator + ``` + +--- + +## `v1.2.0` -> `v1.3.0` + +Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure. + +1. Checkout source code of v1.3.0: + ``` + git checkout v1.3.0 + ``` +1. Update Scylla Operator from deploy directory: + ``` + kubectl -n scylla-operator apply -f deploy/operator + ``` +1. Wait until Scylla Operator is up and running: + ``` + kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com + kubectl -n scylla-operator rollout status deployment.apps/scylla-operator + ``` + +## `v1.1.0` -> `v1.2.0` + +1.2.0 release brought a lot of changes to the Scylla Operator deployment process. +To properly update Scylla Operator one must delete old objects and install updated ones. + +Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure. + +1. Checkout source code of v1.2.0: + ``` + git checkout v1.2.0 + ``` +1. Remove old scylla operator namespace - in our case it's called `scylla-operator-system`: + ``` + kubectl delete namespace scylla-operator-system --wait=true + ``` +1. Remove old webhooks: + ``` + kubectl delete MutatingWebhookConfiguration scylla-operator-mutating-webhook-configuration + kubectl delete ValidatingWebhookConfiguration scylla-operator-validating-webhook-configuration + ``` +1. Install Scylla Operator from deploy directory: + ``` + kubectl -n scylla-operator apply -f deploy/operator + ``` +1. Wait until Scylla Operator is up and running: + ``` + kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com + kubectl -n scylla-operator rollout status deployment.apps/scylla-operator + ``` + +## `v1.0.0` -> `v1.1.0` + +During this update we will change probes and image for Scylla Operator. +A new version brings an automation for upgrade of sidecar image, so a rolling restart of managed Scylla clusters is expected. + +1. Get name of StatefulSet managing Scylla Operator + ```shell + kubectl --namespace scylla-operator-system get sts --selector="control-plane=controller-manager" + + NAME READY AGE + scylla-operator-controller-manager 1/1 95m + ``` + +1. Change probes and used container image by applying following patch: + ```yaml + spec: + template: + spec: + containers: + - name: manager + image: docker.io/scylladb/scylla-operator:1.1.0 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + scheme: HTTP + readinessProbe: + $retainKeys: + - httpGet + httpGet: + path: /readyz + port: 8080 + scheme: HTTP + ``` + To apply above patch save it to file (`operator-patch.yaml` for example) and apply to Operator StatefulSet: + ```shell + kubectl -n scylla-operator-system patch sts scylla-operator-controller-manager --patch "$(cat operator-patch.yaml)" + ``` + + +## `v0.3.0` -> `v1.0.0` + +***Note:*** There's an experimental migration procedure available [here](migration.md). + +`v0.3.0` used a very common name as a CRD kind (`Cluster`). In `v1.0.0` this issue was solved by using less common +kind which is easier to disambiguate. (`ScyllaCluster`). +This change is backward incompatible, so Scylla cluster must be turned off and recreated from scratch. +In case you need to preserve your data, refer to backup and restore guide. + +1. Get list of existing Scylla clusters + ``` + kubectl -n scylla get cluster.scylla.scylladb.com + + NAME AGE + simple-cluster 30m + ``` +1. Delete each one of them + + ``` + kubectl -n scylla delete cluster.scylla.scylladb.com simple-cluster + ``` +1. Make sure you're on `v0.3.0` branch + ``` + git checkout v0.3.0 + ``` +1. Delete existing CRD and Operator + ``` + kubectl delete -f examples/generic/operator.yaml + ``` +1. Checkout `v1.0.0` version + ``` + git checkout v1.0.0 + ``` +1. Install new CRD and Scylla Operator + ``` + kubectl apply -f examples/common/operator.yaml + ``` +1. Migrate your existing Scylla Cluster definition. Change `apiVersion` and `kind` from: + ``` + apiVersion: scylla.scylladb.com/v1alpha1 + kind: Cluster + ``` + to: + ``` + apiVersion: scylla.scylladb.com/v1 + kind: ScyllaCluster + ``` +1. Once your cluster definition is ready, use `kubectl apply` to install fresh Scylla cluster. diff --git a/v1.11/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/v1.11/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000000..eb19f698afc --- /dev/null +++ b/v1.11/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/v1.11/_sphinx_design_static/design-tabs.js b/v1.11/_sphinx_design_static/design-tabs.js new file mode 100644 index 00000000000..36b38cf0d91 --- /dev/null +++ b/v1.11/_sphinx_design_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/v1.11/_static/basic.css b/v1.11/_static/basic.css new file mode 100644 index 00000000000..30fee9d0f76 --- /dev/null +++ b/v1.11/_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/v1.11/_static/check-solid.svg b/v1.11/_static/check-solid.svg new file mode 100644 index 00000000000..92fad4b5c0b --- /dev/null +++ b/v1.11/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v1.11/_static/clipboard.min.js b/v1.11/_static/clipboard.min.js new file mode 100644 index 00000000000..54b3c463811 --- /dev/null +++ b/v1.11/_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/v1.11/_static/copybutton.css b/v1.11/_static/copybutton.css new file mode 100644 index 00000000000..f1916ec7d1b --- /dev/null +++ b/v1.11/_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/v1.11/_static/copybutton.js b/v1.11/_static/copybutton.js new file mode 100644 index 00000000000..2ea7ff3e217 --- /dev/null +++ b/v1.11/_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/v1.11/_static/copybutton_funcs.js b/v1.11/_static/copybutton_funcs.js new file mode 100644 index 00000000000..dbe1aaad79c --- /dev/null +++ b/v1.11/_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/v1.11/_static/css/main.css b/v1.11/_static/css/main.css new file mode 100644 index 00000000000..65eb0a55363 --- /dev/null +++ b/v1.11/_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/v1.11/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/v1.11/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000000..eb19f698afc --- /dev/null +++ b/v1.11/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/v1.11/_static/design-tabs.js b/v1.11/_static/design-tabs.js new file mode 100644 index 00000000000..36b38cf0d91 --- /dev/null +++ b/v1.11/_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/v1.11/_static/doctools.js b/v1.11/_static/doctools.js new file mode 100644 index 00000000000..d06a71d7518 --- /dev/null +++ b/v1.11/_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/v1.11/_static/documentation_options.js b/v1.11/_static/documentation_options.js new file mode 100644 index 00000000000..7e4c114f212 --- /dev/null +++ b/v1.11/_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/v1.11/_static/file.png b/v1.11/_static/file.png new file mode 100644 index 00000000000..a858a410e4f Binary files /dev/null and b/v1.11/_static/file.png differ diff --git a/v1.11/_static/img/banner-background.svg b/v1.11/_static/img/banner-background.svg new file mode 100644 index 00000000000..f8520d5b3e4 --- /dev/null +++ b/v1.11/_static/img/banner-background.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v1.11/_static/img/favicon-228x228.png b/v1.11/_static/img/favicon-228x228.png new file mode 100644 index 00000000000..f30770c7edd Binary files /dev/null and b/v1.11/_static/img/favicon-228x228.png differ diff --git a/v1.11/_static/img/favicon-32x32.png b/v1.11/_static/img/favicon-32x32.png new file mode 100644 index 00000000000..aae1708f26f Binary files /dev/null and b/v1.11/_static/img/favicon-32x32.png differ diff --git a/v1.11/_static/img/favicon.ico b/v1.11/_static/img/favicon.ico new file mode 100644 index 00000000000..6c7484f082f Binary files /dev/null and b/v1.11/_static/img/favicon.ico differ diff --git a/v1.11/_static/img/icons/icon-about-team.svg b/v1.11/_static/img/icons/icon-about-team.svg new file mode 100644 index 00000000000..5448c7f007b --- /dev/null +++ b/v1.11/_static/img/icons/icon-about-team.svg @@ -0,0 +1 @@ +icon-about-team diff --git a/v1.11/_static/img/icons/icon-about-us-m.svg b/v1.11/_static/img/icons/icon-about-us-m.svg new file mode 100644 index 00000000000..09107d9520a --- /dev/null +++ b/v1.11/_static/img/icons/icon-about-us-m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.11/_static/img/icons/icon-about-us.svg b/v1.11/_static/img/icons/icon-about-us.svg new file mode 100644 index 00000000000..1b1fcc83e30 --- /dev/null +++ b/v1.11/_static/img/icons/icon-about-us.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.11/_static/img/icons/icon-alternator.svg b/v1.11/_static/img/icons/icon-alternator.svg new file mode 100644 index 00000000000..7c2b4ebae0d --- /dev/null +++ b/v1.11/_static/img/icons/icon-alternator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.11/_static/img/icons/icon-apps.svg b/v1.11/_static/img/icons/icon-apps.svg new file mode 100644 index 00000000000..7e93612026b --- /dev/null +++ b/v1.11/_static/img/icons/icon-apps.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-architecture.svg b/v1.11/_static/img/icons/icon-architecture.svg new file mode 100644 index 00000000000..67ebbc2f38c --- /dev/null +++ b/v1.11/_static/img/icons/icon-architecture.svg @@ -0,0 +1 @@ +icon-architecture diff --git a/v1.11/_static/img/icons/icon-benchmarks.svg b/v1.11/_static/img/icons/icon-benchmarks.svg new file mode 100644 index 00000000000..e1ce2c1d784 --- /dev/null +++ b/v1.11/_static/img/icons/icon-benchmarks.svg @@ -0,0 +1 @@ +icon-benchmarks diff --git a/v1.11/_static/img/icons/icon-blog.svg b/v1.11/_static/img/icons/icon-blog.svg new file mode 100644 index 00000000000..f4096cbf111 --- /dev/null +++ b/v1.11/_static/img/icons/icon-blog.svg @@ -0,0 +1 @@ +icon-blog2 diff --git a/v1.11/_static/img/icons/icon-careers.svg b/v1.11/_static/img/icons/icon-careers.svg new file mode 100644 index 00000000000..2a7c6ea0b74 --- /dev/null +++ b/v1.11/_static/img/icons/icon-careers.svg @@ -0,0 +1 @@ +icon-careers diff --git a/v1.11/_static/img/icons/icon-chevron-left.svg b/v1.11/_static/img/icons/icon-chevron-left.svg new file mode 100644 index 00000000000..3afa25c4812 --- /dev/null +++ b/v1.11/_static/img/icons/icon-chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.11/_static/img/icons/icon-chevron-right.svg b/v1.11/_static/img/icons/icon-chevron-right.svg new file mode 100644 index 00000000000..44eb829cdcb --- /dev/null +++ b/v1.11/_static/img/icons/icon-chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.11/_static/img/icons/icon-circe.svg b/v1.11/_static/img/icons/icon-circe.svg new file mode 100644 index 00000000000..875e4216707 --- /dev/null +++ b/v1.11/_static/img/icons/icon-circe.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-clock.svg b/v1.11/_static/img/icons/icon-clock.svg new file mode 100644 index 00000000000..8c924698089 --- /dev/null +++ b/v1.11/_static/img/icons/icon-clock.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-close.svg b/v1.11/_static/img/icons/icon-close.svg new file mode 100644 index 00000000000..d1162b73e73 --- /dev/null +++ b/v1.11/_static/img/icons/icon-close.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/v1.11/_static/img/icons/icon-cloud-docs.svg b/v1.11/_static/img/icons/icon-cloud-docs.svg new file mode 100644 index 00000000000..a9069bb6e5c --- /dev/null +++ b/v1.11/_static/img/icons/icon-cloud-docs.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-cloud.svg b/v1.11/_static/img/icons/icon-cloud.svg new file mode 100644 index 00000000000..cfb2318daef --- /dev/null +++ b/v1.11/_static/img/icons/icon-cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.11/_static/img/icons/icon-comparison.svg b/v1.11/_static/img/icons/icon-comparison.svg new file mode 100644 index 00000000000..49d809a5df4 --- /dev/null +++ b/v1.11/_static/img/icons/icon-comparison.svg @@ -0,0 +1 @@ +icon-comparison diff --git a/v1.11/_static/img/icons/icon-contact-us.svg b/v1.11/_static/img/icons/icon-contact-us.svg new file mode 100644 index 00000000000..9df3145dd21 --- /dev/null +++ b/v1.11/_static/img/icons/icon-contact-us.svg @@ -0,0 +1 @@ +icon-contact-us diff --git a/v1.11/_static/img/icons/icon-developers-blog.svg b/v1.11/_static/img/icons/icon-developers-blog.svg new file mode 100644 index 00000000000..ee804197a0b --- /dev/null +++ b/v1.11/_static/img/icons/icon-developers-blog.svg @@ -0,0 +1 @@ +icon-developers-blog diff --git a/v1.11/_static/img/icons/icon-docs.svg b/v1.11/_static/img/icons/icon-docs.svg new file mode 100644 index 00000000000..5501492f3e0 --- /dev/null +++ b/v1.11/_static/img/icons/icon-docs.svg @@ -0,0 +1 @@ +icon-docs diff --git a/v1.11/_static/img/icons/icon-enterprise-m.svg b/v1.11/_static/img/icons/icon-enterprise-m.svg new file mode 100644 index 00000000000..97be900b501 --- /dev/null +++ b/v1.11/_static/img/icons/icon-enterprise-m.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.11/_static/img/icons/icon-enterprise.svg b/v1.11/_static/img/icons/icon-enterprise.svg new file mode 100644 index 00000000000..ee1ac26283d --- /dev/null +++ b/v1.11/_static/img/icons/icon-enterprise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.11/_static/img/icons/icon-events.svg b/v1.11/_static/img/icons/icon-events.svg new file mode 100644 index 00000000000..ba5f2118644 --- /dev/null +++ b/v1.11/_static/img/icons/icon-events.svg @@ -0,0 +1 @@ +icon-events diff --git a/v1.11/_static/img/icons/icon-exclamation.svg b/v1.11/_static/img/icons/icon-exclamation.svg new file mode 100644 index 00000000000..a7eb4b77a42 --- /dev/null +++ b/v1.11/_static/img/icons/icon-exclamation.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v1.11/_static/img/icons/icon-expand.svg b/v1.11/_static/img/icons/icon-expand.svg new file mode 100644 index 00000000000..38065653675 --- /dev/null +++ b/v1.11/_static/img/icons/icon-expand.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/v1.11/_static/img/icons/icon-forum.svg b/v1.11/_static/img/icons/icon-forum.svg new file mode 100644 index 00000000000..37a709f7a8f --- /dev/null +++ b/v1.11/_static/img/icons/icon-forum.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-getting-started.svg b/v1.11/_static/img/icons/icon-getting-started.svg new file mode 100644 index 00000000000..702500be409 --- /dev/null +++ b/v1.11/_static/img/icons/icon-getting-started.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-glossary.svg b/v1.11/_static/img/icons/icon-glossary.svg new file mode 100644 index 00000000000..e8329c2afee --- /dev/null +++ b/v1.11/_static/img/icons/icon-glossary.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-home.svg b/v1.11/_static/img/icons/icon-home.svg new file mode 100644 index 00000000000..f0b9c25419c --- /dev/null +++ b/v1.11/_static/img/icons/icon-home.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-infoworld.svg b/v1.11/_static/img/icons/icon-infoworld.svg new file mode 100644 index 00000000000..906e87279c2 --- /dev/null +++ b/v1.11/_static/img/icons/icon-infoworld.svg @@ -0,0 +1 @@ +icon-infoworld diff --git a/v1.11/_static/img/icons/icon-integrations.svg b/v1.11/_static/img/icons/icon-integrations.svg new file mode 100644 index 00000000000..1ef0920d49e --- /dev/null +++ b/v1.11/_static/img/icons/icon-integrations.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-knowledge-base.svg b/v1.11/_static/img/icons/icon-knowledge-base.svg new file mode 100644 index 00000000000..884451270d2 --- /dev/null +++ b/v1.11/_static/img/icons/icon-knowledge-base.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-less.svg b/v1.11/_static/img/icons/icon-less.svg new file mode 100644 index 00000000000..3094127decf --- /dev/null +++ b/v1.11/_static/img/icons/icon-less.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v1.11/_static/img/icons/icon-live-test.svg b/v1.11/_static/img/icons/icon-live-test.svg new file mode 100644 index 00000000000..dcb5916c264 --- /dev/null +++ b/v1.11/_static/img/icons/icon-live-test.svg @@ -0,0 +1 @@ +icon-live-test diff --git a/v1.11/_static/img/icons/icon-mail-list.svg b/v1.11/_static/img/icons/icon-mail-list.svg new file mode 100644 index 00000000000..0e6192a352c --- /dev/null +++ b/v1.11/_static/img/icons/icon-mail-list.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-manager.svg b/v1.11/_static/img/icons/icon-manager.svg new file mode 100644 index 00000000000..02b4e425beb --- /dev/null +++ b/v1.11/_static/img/icons/icon-manager.svg @@ -0,0 +1 @@ +icon-manager diff --git a/v1.11/_static/img/icons/icon-memory-management.svg b/v1.11/_static/img/icons/icon-memory-management.svg new file mode 100644 index 00000000000..e34eb4504f7 --- /dev/null +++ b/v1.11/_static/img/icons/icon-memory-management.svg @@ -0,0 +1 @@ +icon-memory-management diff --git a/v1.11/_static/img/icons/icon-modeling.svg b/v1.11/_static/img/icons/icon-modeling.svg new file mode 100644 index 00000000000..97fa3a0e213 --- /dev/null +++ b/v1.11/_static/img/icons/icon-modeling.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-monitoring.svg b/v1.11/_static/img/icons/icon-monitoring.svg new file mode 100644 index 00000000000..80b3787f668 --- /dev/null +++ b/v1.11/_static/img/icons/icon-monitoring.svg @@ -0,0 +1 @@ +icon-monitoring diff --git a/v1.11/_static/img/icons/icon-networking.svg b/v1.11/_static/img/icons/icon-networking.svg new file mode 100644 index 00000000000..40a3fd5f6f1 --- /dev/null +++ b/v1.11/_static/img/icons/icon-networking.svg @@ -0,0 +1 @@ +icon-networking diff --git a/v1.11/_static/img/icons/icon-news.svg b/v1.11/_static/img/icons/icon-news.svg new file mode 100644 index 00000000000..a952b59937d --- /dev/null +++ b/v1.11/_static/img/icons/icon-news.svg @@ -0,0 +1 @@ +icon-news diff --git a/v1.11/_static/img/icons/icon-newsletter.svg b/v1.11/_static/img/icons/icon-newsletter.svg new file mode 100644 index 00000000000..5b8d47eb157 --- /dev/null +++ b/v1.11/_static/img/icons/icon-newsletter.svg @@ -0,0 +1 @@ +icon-newsletter diff --git a/v1.11/_static/img/icons/icon-nsql-guides.svg b/v1.11/_static/img/icons/icon-nsql-guides.svg new file mode 100644 index 00000000000..60ebab37953 --- /dev/null +++ b/v1.11/_static/img/icons/icon-nsql-guides.svg @@ -0,0 +1 @@ +icon-nsql-guides diff --git a/v1.11/_static/img/icons/icon-open-source.svg b/v1.11/_static/img/icons/icon-open-source.svg new file mode 100644 index 00000000000..98c2ea7d5bf --- /dev/null +++ b/v1.11/_static/img/icons/icon-open-source.svg @@ -0,0 +1 @@ +icon-open-source diff --git a/v1.11/_static/img/icons/icon-operator.svg b/v1.11/_static/img/icons/icon-operator.svg new file mode 100644 index 00000000000..bb7d8d3ea86 --- /dev/null +++ b/v1.11/_static/img/icons/icon-operator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.11/_static/img/icons/icon-overview.svg b/v1.11/_static/img/icons/icon-overview.svg new file mode 100644 index 00000000000..515c1528a2a --- /dev/null +++ b/v1.11/_static/img/icons/icon-overview.svg @@ -0,0 +1 @@ +icon-overview diff --git a/v1.11/_static/img/icons/icon-partners.svg b/v1.11/_static/img/icons/icon-partners.svg new file mode 100644 index 00000000000..d0146fc4972 --- /dev/null +++ b/v1.11/_static/img/icons/icon-partners.svg @@ -0,0 +1 @@ +icon-partners diff --git a/v1.11/_static/img/icons/icon-plus.svg b/v1.11/_static/img/icons/icon-plus.svg new file mode 100644 index 00000000000..5757435085a --- /dev/null +++ b/v1.11/_static/img/icons/icon-plus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v1.11/_static/img/icons/icon-pricing.svg b/v1.11/_static/img/icons/icon-pricing.svg new file mode 100644 index 00000000000..74b01db1684 --- /dev/null +++ b/v1.11/_static/img/icons/icon-pricing.svg @@ -0,0 +1 @@ +icon-pricing$ diff --git a/v1.11/_static/img/icons/icon-release-notes.svg b/v1.11/_static/img/icons/icon-release-notes.svg new file mode 100644 index 00000000000..80c490c7b01 --- /dev/null +++ b/v1.11/_static/img/icons/icon-release-notes.svg @@ -0,0 +1 @@ +icon-release-notes diff --git a/v1.11/_static/img/icons/icon-resource-center.svg b/v1.11/_static/img/icons/icon-resource-center.svg new file mode 100644 index 00000000000..6e3ab08e792 --- /dev/null +++ b/v1.11/_static/img/icons/icon-resource-center.svg @@ -0,0 +1 @@ +icon-ressource-center diff --git a/v1.11/_static/img/icons/icon-roadmap.svg b/v1.11/_static/img/icons/icon-roadmap.svg new file mode 100644 index 00000000000..c8cbf67c8cf --- /dev/null +++ b/v1.11/_static/img/icons/icon-roadmap.svg @@ -0,0 +1 @@ +icon-roadmap-4 diff --git a/v1.11/_static/img/icons/icon-search.svg b/v1.11/_static/img/icons/icon-search.svg new file mode 100644 index 00000000000..81aae93eef6 --- /dev/null +++ b/v1.11/_static/img/icons/icon-search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v1.11/_static/img/icons/icon-slack.svg b/v1.11/_static/img/icons/icon-slack.svg new file mode 100644 index 00000000000..fc164ea1e77 --- /dev/null +++ b/v1.11/_static/img/icons/icon-slack.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-stack-overflow.svg b/v1.11/_static/img/icons/icon-stack-overflow.svg new file mode 100644 index 00000000000..bebe9b82742 --- /dev/null +++ b/v1.11/_static/img/icons/icon-stack-overflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v1.11/_static/img/icons/icon-summit.svg b/v1.11/_static/img/icons/icon-summit.svg new file mode 100644 index 00000000000..4b900bd0c0a --- /dev/null +++ b/v1.11/_static/img/icons/icon-summit.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/icons/icon-support.svg b/v1.11/_static/img/icons/icon-support.svg new file mode 100644 index 00000000000..a4228b34e86 --- /dev/null +++ b/v1.11/_static/img/icons/icon-support.svg @@ -0,0 +1 @@ +icon-support diff --git a/v1.11/_static/img/icons/icon-tech-talks.svg b/v1.11/_static/img/icons/icon-tech-talks.svg new file mode 100644 index 00000000000..df42b5522ba --- /dev/null +++ b/v1.11/_static/img/icons/icon-tech-talks.svg @@ -0,0 +1 @@ +icon-tech-talks diff --git a/v1.11/_static/img/icons/icon-testing.svg b/v1.11/_static/img/icons/icon-testing.svg new file mode 100644 index 00000000000..2fe54efdbc3 --- /dev/null +++ b/v1.11/_static/img/icons/icon-testing.svg @@ -0,0 +1 @@ +icon-testing diff --git a/v1.11/_static/img/icons/icon-thumbs-down.svg b/v1.11/_static/img/icons/icon-thumbs-down.svg new file mode 100644 index 00000000000..3e7bcd6d905 --- /dev/null +++ b/v1.11/_static/img/icons/icon-thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.11/_static/img/icons/icon-thumbs-up.svg b/v1.11/_static/img/icons/icon-thumbs-up.svg new file mode 100644 index 00000000000..226c44d853c --- /dev/null +++ b/v1.11/_static/img/icons/icon-thumbs-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.11/_static/img/icons/icon-tip.svg b/v1.11/_static/img/icons/icon-tip.svg new file mode 100644 index 00000000000..bf7aa6af840 --- /dev/null +++ b/v1.11/_static/img/icons/icon-tip.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/v1.11/_static/img/icons/icon-training.svg b/v1.11/_static/img/icons/icon-training.svg new file mode 100644 index 00000000000..08b95a88eda --- /dev/null +++ b/v1.11/_static/img/icons/icon-training.svg @@ -0,0 +1 @@ +icon-training diff --git a/v1.11/_static/img/icons/icon-triangle-down.svg b/v1.11/_static/img/icons/icon-triangle-down.svg new file mode 100644 index 00000000000..e8ae088106f --- /dev/null +++ b/v1.11/_static/img/icons/icon-triangle-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.11/_static/img/icons/icon-university.svg b/v1.11/_static/img/icons/icon-university.svg new file mode 100644 index 00000000000..f7547ab9599 --- /dev/null +++ b/v1.11/_static/img/icons/icon-university.svg @@ -0,0 +1 @@ +icon-university diff --git a/v1.11/_static/img/icons/icon-users-blog.svg b/v1.11/_static/img/icons/icon-users-blog.svg new file mode 100644 index 00000000000..47e56cddcf7 --- /dev/null +++ b/v1.11/_static/img/icons/icon-users-blog.svg @@ -0,0 +1 @@ +icon-users-blog diff --git a/v1.11/_static/img/icons/icon-warning.svg b/v1.11/_static/img/icons/icon-warning.svg new file mode 100644 index 00000000000..e4b1d40331b --- /dev/null +++ b/v1.11/_static/img/icons/icon-warning.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v1.11/_static/img/icons/icon-webinars.svg b/v1.11/_static/img/icons/icon-webinars.svg new file mode 100644 index 00000000000..5e9f5cd4270 --- /dev/null +++ b/v1.11/_static/img/icons/icon-webinars.svg @@ -0,0 +1 @@ +icon-webinars diff --git a/v1.11/_static/img/icons/icon-whitepapers.svg b/v1.11/_static/img/icons/icon-whitepapers.svg new file mode 100644 index 00000000000..3351e51d23c --- /dev/null +++ b/v1.11/_static/img/icons/icon-whitepapers.svg @@ -0,0 +1 @@ +icon-whitepapers diff --git a/v1.11/_static/img/icons/icon-workshop.svg b/v1.11/_static/img/icons/icon-workshop.svg new file mode 100644 index 00000000000..5206e58e986 --- /dev/null +++ b/v1.11/_static/img/icons/icon-workshop.svg @@ -0,0 +1 @@ + diff --git a/v1.11/_static/img/logo-docs.svg b/v1.11/_static/img/logo-docs.svg new file mode 100644 index 00000000000..4fff669cb6f --- /dev/null +++ b/v1.11/_static/img/logo-docs.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.11/_static/img/logo-scylla-horizontal-RGB.svg b/v1.11/_static/img/logo-scylla-horizontal-RGB.svg new file mode 100644 index 00000000000..b5022d7c4dc --- /dev/null +++ b/v1.11/_static/img/logo-scylla-horizontal-RGB.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.11/_static/img/mascots/404.jpg b/v1.11/_static/img/mascots/404.jpg new file mode 100644 index 00000000000..769fa0889f8 Binary files /dev/null and b/v1.11/_static/img/mascots/404.jpg differ diff --git a/v1.11/_static/img/mascots/scylla-3monsters.png b/v1.11/_static/img/mascots/scylla-3monsters.png new file mode 100644 index 00000000000..7c06d01674a Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-3monsters.png differ diff --git a/v1.11/_static/img/mascots/scylla-advisor-crystal.png b/v1.11/_static/img/mascots/scylla-advisor-crystal.png new file mode 100644 index 00000000000..d33fddd62f0 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-advisor-crystal.png differ diff --git a/v1.11/_static/img/mascots/scylla-alternator.svg b/v1.11/_static/img/mascots/scylla-alternator.svg new file mode 100644 index 00000000000..0462f893d5f --- /dev/null +++ b/v1.11/_static/img/mascots/scylla-alternator.svg @@ -0,0 +1 @@ +scylla-alternator diff --git a/v1.11/_static/img/mascots/scylla-cloud.svg b/v1.11/_static/img/mascots/scylla-cloud.svg new file mode 100644 index 00000000000..a6c6a26fc99 --- /dev/null +++ b/v1.11/_static/img/mascots/scylla-cloud.svg @@ -0,0 +1 @@ +scylla-cloud diff --git a/v1.11/_static/img/mascots/scylla-computer-3-monsters.png b/v1.11/_static/img/mascots/scylla-computer-3-monsters.png new file mode 100644 index 00000000000..d0368a7027b Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-computer-3-monsters.png differ diff --git a/v1.11/_static/img/mascots/scylla-computer-headset.png b/v1.11/_static/img/mascots/scylla-computer-headset.png new file mode 100644 index 00000000000..0cdadaa2167 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-computer-headset.png differ diff --git a/v1.11/_static/img/mascots/scylla-cup-number-one.png b/v1.11/_static/img/mascots/scylla-cup-number-one.png new file mode 100644 index 00000000000..e889f4e368e Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-cup-number-one.png differ diff --git a/v1.11/_static/img/mascots/scylla-docs.svg b/v1.11/_static/img/mascots/scylla-docs.svg new file mode 100644 index 00000000000..a5bce950c25 --- /dev/null +++ b/v1.11/_static/img/mascots/scylla-docs.svg @@ -0,0 +1 @@ +scylla-docs diff --git a/v1.11/_static/img/mascots/scylla-drivers.svg b/v1.11/_static/img/mascots/scylla-drivers.svg new file mode 100644 index 00000000000..6012e71679b --- /dev/null +++ b/v1.11/_static/img/mascots/scylla-drivers.svg @@ -0,0 +1 @@ +scylla-manager diff --git a/v1.11/_static/img/mascots/scylla-enterprise.svg b/v1.11/_static/img/mascots/scylla-enterprise.svg new file mode 100644 index 00000000000..a1aa0b46ac1 --- /dev/null +++ b/v1.11/_static/img/mascots/scylla-enterprise.svg @@ -0,0 +1 @@ +scylla-enterprise diff --git a/v1.11/_static/img/mascots/scylla-forklift-boxes.png b/v1.11/_static/img/mascots/scylla-forklift-boxes.png new file mode 100644 index 00000000000..f64c29e6c7c Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-forklift-boxes.png differ diff --git a/v1.11/_static/img/mascots/scylla-forklift-migration.png b/v1.11/_static/img/mascots/scylla-forklift-migration.png new file mode 100644 index 00000000000..d2f645c645a Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-forklift-migration.png differ diff --git a/v1.11/_static/img/mascots/scylla-gear.png b/v1.11/_static/img/mascots/scylla-gear.png new file mode 100644 index 00000000000..0f53b26afa5 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-gear.png differ diff --git a/v1.11/_static/img/mascots/scylla-hardhat.png b/v1.11/_static/img/mascots/scylla-hardhat.png new file mode 100644 index 00000000000..630f2d90942 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-hardhat.png differ diff --git a/v1.11/_static/img/mascots/scylla-headband.png b/v1.11/_static/img/mascots/scylla-headband.png new file mode 100644 index 00000000000..c87abe684d5 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-headband.png differ diff --git a/v1.11/_static/img/mascots/scylla-headset.png b/v1.11/_static/img/mascots/scylla-headset.png new file mode 100644 index 00000000000..ba52cd223db Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-headset.png differ diff --git a/v1.11/_static/img/mascots/scylla-hearts.png b/v1.11/_static/img/mascots/scylla-hearts.png new file mode 100644 index 00000000000..cef08c8654a Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-hearts.png differ diff --git a/v1.11/_static/img/mascots/scylla-looking-down.png b/v1.11/_static/img/mascots/scylla-looking-down.png new file mode 100644 index 00000000000..75cccbfdf12 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-looking-down.png differ diff --git a/v1.11/_static/img/mascots/scylla-looking-up.png b/v1.11/_static/img/mascots/scylla-looking-up.png new file mode 100644 index 00000000000..6f10405f218 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-looking-up.png differ diff --git a/v1.11/_static/img/mascots/scylla-magnifying-glass-fronting.png b/v1.11/_static/img/mascots/scylla-magnifying-glass-fronting.png new file mode 100644 index 00000000000..e368cae169c Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-magnifying-glass-fronting.png differ diff --git a/v1.11/_static/img/mascots/scylla-magnifying-glass.png b/v1.11/_static/img/mascots/scylla-magnifying-glass.png new file mode 100644 index 00000000000..74ad6695005 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-magnifying-glass.png differ diff --git a/v1.11/_static/img/mascots/scylla-manager.svg b/v1.11/_static/img/mascots/scylla-manager.svg new file mode 100644 index 00000000000..6ba9ed937c9 --- /dev/null +++ b/v1.11/_static/img/mascots/scylla-manager.svg @@ -0,0 +1 @@ +scylla-manager-2 diff --git a/v1.11/_static/img/mascots/scylla-monitor.svg b/v1.11/_static/img/mascots/scylla-monitor.svg new file mode 100644 index 00000000000..48bec7dde32 --- /dev/null +++ b/v1.11/_static/img/mascots/scylla-monitor.svg @@ -0,0 +1 @@ +scylla-monitor diff --git a/v1.11/_static/img/mascots/scylla-movement-fast.png b/v1.11/_static/img/mascots/scylla-movement-fast.png new file mode 100644 index 00000000000..956d1dd0e22 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-movement-fast.png differ diff --git a/v1.11/_static/img/mascots/scylla-movement.png b/v1.11/_static/img/mascots/scylla-movement.png new file mode 100644 index 00000000000..7ee2b043384 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-movement.png differ diff --git a/v1.11/_static/img/mascots/scylla-onpremise.png b/v1.11/_static/img/mascots/scylla-onpremise.png new file mode 100644 index 00000000000..3b2dc8f1a2c Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-onpremise.png differ diff --git a/v1.11/_static/img/mascots/scylla-opensource.svg b/v1.11/_static/img/mascots/scylla-opensource.svg new file mode 100644 index 00000000000..299e9cb9955 --- /dev/null +++ b/v1.11/_static/img/mascots/scylla-opensource.svg @@ -0,0 +1 @@ +Plan de travail 1 diff --git a/v1.11/_static/img/mascots/scylla-operator.svg b/v1.11/_static/img/mascots/scylla-operator.svg new file mode 100644 index 00000000000..655a450b2a4 --- /dev/null +++ b/v1.11/_static/img/mascots/scylla-operator.svg @@ -0,0 +1 @@ +scylla-operator diff --git a/v1.11/_static/img/mascots/scylla-plugin.png b/v1.11/_static/img/mascots/scylla-plugin.png new file mode 100644 index 00000000000..b28dc857ccf Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-plugin.png differ diff --git a/v1.11/_static/img/mascots/scylla-release-mascot.png b/v1.11/_static/img/mascots/scylla-release-mascot.png new file mode 100644 index 00000000000..09342ac6875 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-release-mascot.png differ diff --git a/v1.11/_static/img/mascots/scylla-repair.png b/v1.11/_static/img/mascots/scylla-repair.png new file mode 100644 index 00000000000..9b4c613e702 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-repair.png differ diff --git a/v1.11/_static/img/mascots/scylla-server.png b/v1.11/_static/img/mascots/scylla-server.png new file mode 100644 index 00000000000..96dc785298b Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-server.png differ diff --git a/v1.11/_static/img/mascots/scylla-sleeping.png b/v1.11/_static/img/mascots/scylla-sleeping.png new file mode 100644 index 00000000000..f88598e05ad Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-sleeping.png differ diff --git a/v1.11/_static/img/mascots/scylla-tall-measure.png b/v1.11/_static/img/mascots/scylla-tall-measure.png new file mode 100644 index 00000000000..6f0ca146c0d Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-tall-measure.png differ diff --git a/v1.11/_static/img/mascots/scylla-university.png b/v1.11/_static/img/mascots/scylla-university.png new file mode 100644 index 00000000000..b3d0621193f Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-university.png differ diff --git a/v1.11/_static/img/mascots/scylla-weights.png b/v1.11/_static/img/mascots/scylla-weights.png new file mode 100644 index 00000000000..b070bb022cb Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-weights.png differ diff --git a/v1.11/_static/img/mascots/scylla-window-cleaning.png b/v1.11/_static/img/mascots/scylla-window-cleaning.png new file mode 100644 index 00000000000..6a8b16a6b4e Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-window-cleaning.png differ diff --git a/v1.11/_static/img/mascots/scylla-with-computer-2.png b/v1.11/_static/img/mascots/scylla-with-computer-2.png new file mode 100644 index 00000000000..f3b8b2984f6 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-with-computer-2.png differ diff --git a/v1.11/_static/img/mascots/scylla-with-computer.png b/v1.11/_static/img/mascots/scylla-with-computer.png new file mode 100644 index 00000000000..b38a6fbbe04 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-with-computer.png differ diff --git a/v1.11/_static/img/mascots/scylla-with-linux.png b/v1.11/_static/img/mascots/scylla-with-linux.png new file mode 100644 index 00000000000..954bf13bc29 Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-with-linux.png differ diff --git a/v1.11/_static/img/mascots/scylla-writting.png b/v1.11/_static/img/mascots/scylla-writting.png new file mode 100644 index 00000000000..d35a13d380d Binary files /dev/null and b/v1.11/_static/img/mascots/scylla-writting.png differ diff --git a/v1.11/_static/img/menu.svg b/v1.11/_static/img/menu.svg new file mode 100644 index 00000000000..30ea1d901e1 --- /dev/null +++ b/v1.11/_static/img/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.11/_static/js/main.bundle.js b/v1.11/_static/js/main.bundle.js new file mode 100644 index 00000000000..190a41642ef --- /dev/null +++ b/v1.11/_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 +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Contributing to Scylla Operator

            +
            +

            Prerequisites

            +

            To develop on scylla-operator, your environment must have the following:

            +
              +
            1. Go 1.13

              +
                +
              • Make sure GOPATH is set to GOPATH=$HOME/go.

              • +
              +
            2. +
            3. Kustomize v3.1.0

            4. +
            5. kubebuilder v2.3.1

            6. +
            7. Docker

            8. +
            9. Git client installed

            10. +
            11. Github account

            12. +
            +

            To install all dependencies (Go, kustomize, kubebuilder, dep), simply run:

            +
            ./install-dependencies.sh
            +
            +
            +
            +
            +

            Initial Setup

            +
            +

            Create a Fork

            +

            From your browser navigate to http://github.com/scylladb/scylla-operator and click the “Fork” button.

            +
            +
            +

            Clone Your Fork

            +

            Open a console window and do the following:

            +
            # Create the scylla operator repo path
            +mkdir -p $GOPATH/src/github.com/scylladb
            +
            +# Navigate to the local repo path and clone your fork
            +cd $GOPATH/src/github.com/scylladb
            +
            +# Clone your fork, where <user> is your GitHub account name
            +git clone https://github.com/<user>/scylla-operator.git
            +
            +
            +
            +
            +

            Add Upstream Remote

            +

            First you will need to add the upstream remote to your local git:

            +
            # Add 'upstream' to the list of remotes
            +git remote add upstream https://github.com/scylladb/scylla-operator.git
            +
            +# Verify the remote was added
            +git remote -v
            +
            +
            +

            Now you should have at least origin and upstream remotes. You can also add other remotes to collaborate with other contributors.

            +
            +
            +
            +

            Development

            +

            To add a feature or to make a bug fix, you will need to create a branch in your fork and then submit a pull request (PR) from the branch.

            +
            +

            Building the project

            +

            You can build the project using the Makefile commands:

            +
              +
            • Open the Makefile and change the IMG environment variable to a repository you have access to.

            • +
            • Run make docker-push and wait for the image to be built and uploaded in your repo.

            • +
            +
            +
            +

            Create a Branch

            +

            From a console, create a new branch based on your fork and start working on it:

            +
            # Ensure all your remotes are up to date with the latest
            +git fetch --all
            +
            +# Create a new branch that is based off upstream master.  Give it a simple, but descriptive name.
            +# Generally it will be two to three words separated by dashes and without numbers.
            +git checkout -b feature-name upstream/master
            +
            +
            +

            Now you are ready to make the changes and commit to your branch.

            +
            +
            +

            Updating Your Fork

            +

            During the development lifecycle, you will need to keep up-to-date with the latest upstream master. As others on the team push changes, you will need to rebase your commits on top of the latest. This avoids unnecessary merge commits and keeps the commit history clean.

            +

            Whenever you need to update your local repository, you never want to merge. You always will rebase. Otherwise you will end up with merge commits in the git history. If you have any modified files, you will first have to stash them (git stash save -u "<some description>").

            +
            git fetch --all
            +git rebase upstream/master
            +
            +
            +

            Rebasing is a very powerful feature of Git. You need to understand how it works or else you will risk losing your work. Read about it in the Git documentation, it will be well worth it. In a nutshell, rebasing does the following:

            +
              +
            • “Unwinds” your local commits. Your local commits are removed temporarily from the history.

            • +
            • The latest changes from upstream are added to the history

            • +
            • Your local commits are re-applied one by one

            • +
            • If there are merge conflicts, you will be prompted to fix them before continuing. Read the output closely. It will tell you how to complete the rebase.

            • +
            • When done rebasing, you will see all of your commits in the history.

            • +
            +
            +
            +
            +

            Submitting a Pull Request

            +

            Once you have implemented the feature or bug fix in your branch, you will open a PR to the upstream repo. Before opening the PR ensure you have added unit tests, are passing the integration tests, cleaned your commit history, and have rebased on the latest upstream.

            +

            In order to open a pull request (PR) it is required to be up to date with the latest changes upstream. If other commits are pushed upstream before your PR is merged, you will also need to rebase again before it will be merged.

            +
            +

            Commit History

            +

            To prepare your branch to open a PR, you will need to have the minimal number of logical commits so we can maintain +a clean commit history. Most commonly a PR will include a single commit where all changes are squashed, although +sometimes there will be multiple logical commits.

            +
            # Inspect your commit history to determine if you need to squash commits
            +git log
            +
            +# Rebase the commits and edit, squash, or even reorder them as you determine will keep the history clean.
            +# In this example, the last 5 commits will be opened in the git rebase tool.
            +git rebase -i HEAD~5
            +
            +
            +

            Once your commit history is clean, ensure you have based on the latest upstream before you open the PR.

            +
            +
            +

            Commit messages

            +

            Please make the first line of your commit message a summary of the change that a user (not a developer) of Operator would like to read, +and prefix it with the most relevant directory of the change followed by a colon. +The changelog gets made by looking at just these first lines so make it good!

            +

            If you have more to say about the commit, then enter a blank line and carry on the description. +Remember to say why the change was needed - the commit itself shows what was changed.

            +

            Writing more is better than less. Comparing the behaviour before the change to that after the change is very useful. +Imagine you are writing to yourself in 12 months time when you’ve forgotten everything about what you just did, and you need to get up to speed quickly.

            +

            If the change fixes an issue then write Fixes #1234 in the commit message. +This can be on the subject line if it will fit. If you don’t want to close the associated issue just put #1234 and the change will get linked into the issue.

            +

            Here is an example of a short commit message:

            +
            sidecar: log on reconcile loop - fixes #1234
            +
            +
            +

            And here is an example of a longer one:

            +
            
            +api: now supports host networking (#1234)
            +
            +The operator CRD now has a "network" property that can be used to
            +select host networking as well as setting the apropriate DNS policy.
            +
            +Fixes #1234
            +
            +
            +
            +
            +

            Submitting

            +

            Go to the Scylla Operator github to open the PR. If you have pushed recently, you should see an obvious link to open the PR. If you have not pushed recently, go to the Pull Request tab and select your fork and branch for the PR.

            +

            After the PR is open, you can make changes simply by pushing new commits. Your PR will track the changes in your fork and update automatically.

            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/eks.html b/v1.11/eks.html new file mode 100644 index 00000000000..fbd375a0086 --- /dev/null +++ b/v1.11/eks.html @@ -0,0 +1,729 @@ + + + + + + + + + + + + + Deploying Scylla on EKS | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Deploying Scylla on EKS

            +

            This guide is focused on deploying Scylla on EKS with improved performance. +Performance tricks used by the script won’t work with different machine tiers. +It sets up the kubelets on EKS nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

            +

            Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

            +
            +

            TL;DR;

            +

            If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

            +
            # Edit according to your preference
            +EKS_REGION=us-east-1
            +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
            +
            +# From inside the examples/eks folder
            +cd examples/eks
            +./eks.sh -z "$EKS_ZONES" -r "$EKS_REGION"
            +
            +
            +

            After you deploy, see how you can benchmark your cluster with cassandra-stress.

            +
            +
            +

            Walkthrough

            +
            +

            EKS Setup

            +
            +

            Configure environment variables

            +

            First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

            +
            EKS_REGION=us-east-1
            +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
            +CLUSTER_NAME=scylla-demo
            +
            +
            +
            +
            +

            Creating an EKS cluster

            +

            For this guide, we’ll create an EKS cluster with the following:

            +
              +
            • A NodeGroup of 3 i3-2xlarge Nodes, where the Scylla Pods will be deployed. These nodes will only accept pods having scylla-clusters toleration.

            • +
            +
              - name: scylla-pool
            +    instanceType: i3.2xlarge
            +    desiredCapacity: 3
            +    labels:
            +      scylla.scylladb.com/node-type: scylla
            +    taints:
            +      role: "scylla-clusters:NoSchedule"
            +    ssh:
            +      allow: true
            +    kubeletExtraConfig:
            +      cpuManagerPolicy: static
            +
            +
            +
              +
            • A NodeGroup of 4 c4.2xlarge Nodes to deploy cassandra-stress later on. These nodes will only accept pods having cassandra-stress toleration.

            • +
            +
              - name: cassandra-stress-pool
            +    instanceType: c4.2xlarge
            +    desiredCapacity: 4
            +    labels:
            +      pool: "cassandra-stress-pool"
            +    taints:
            +      role: "cassandra-stress:NoSchedule"
            +    ssh:
            +      allow: true
            +
            +
            +
              +
            • A NodeGroup of 1 i3.large Node, where the monitoring stack and operator will be deployed.

            • +
            +
              - name: monitoring-pool
            +    instanceType: i3.large
            +    desiredCapacity: 1
            +    labels:
            +      pool: "monitoring-pool"
            +    ssh:
            +      allow: true
            +
            +
            +
            +
            +
            +

            Prerequisites

            +
            +

            Installing script third party dependencies

            +

            Script requires several dependencies:

            +
              +
            • eksctl - See: https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html

            • +
            • kubectl - See: https://kubernetes.io/docs/tasks/tools/install-kubectl/

            • +
            +
            +
            +
            +

            Deploying ScyllaDB Operator

            +

            Refer to Deploying Scylla on a Kubernetes Cluster in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites.

            +
            +

            Setting up nodes for ScyllaDB

            +

            ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you’ll first need to form a RAID array from those disks. +NodeConfig performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in Performance tuning section of ScyllaDB Operator’s documentation.

            +

            Deploy NodeConfig to let it take care of the above operations:

            +
            kubectl apply --server-side -f examples/eks/nodeconfig-alpha.yaml
            +
            +
            +
            +
            +

            Deploying Local Volume Provisioner

            +

            Afterwards, deploy ScyllaDB’s Local Volume Provisioner, capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays.

            +
            kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/
            +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml
            +
            +
            +
            +
            +
            +

            Deploying ScyllaDB

            +

            Now you can follow the steps described in Deploying Scylla on a Kubernetes Cluster to launch your ScyllaDB cluster in a highly performant environment.

            +
            +

            Accessing the database

            +

            Instructions on how to access the database can also be found in the generic guide.

            +
            +
            +
            +

            Deleting an EKS cluster

            +

            Once you are done with your experiments delete your cluster using the following command:

            +
            eksctl delete cluster "${CLUSTER_NAME}"
            +
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/exposing.html b/v1.11/exposing.html new file mode 100644 index 00000000000..a898a097898 --- /dev/null +++ b/v1.11/exposing.html @@ -0,0 +1,875 @@ + + + + + + + + + + + + + Exposing ScyllaCluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Exposing ScyllaCluster

            +

            This document explains how ScyllaDB Operator exposes ScyllaClusters in different network setups. +A ScyllaCluster can be exposed in various network configurations, independently to clients and nodes.

            +
            +

            Note

            +

            ScyllaClusters can be only exposed when the ScyllaDB version used version is >=2023.1 ScyllaDB Enterprise or >=5.2 ScyllaDB Open Source.

            +
            +
            +

            Expose Options

            +

            exposeOptions specifies configuration options for exposing ScyllaCluster’s. +A ScyllaCluster created without any exposeOptions is equivalent to the following:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +     type: ClusterIP
            +    broadcastOptions:
            +      clients:
            +        type: ServiceClusterIP
            +      nodes:
            +        type: ServiceClusterIP
            +
            +
            +

            The following sections cover what every field controls and what the configuration options are.

            +
            +

            Node Service Template

            +

            nodeService serves as a template for a node-dedicated Service managed by the Scylla Operator for each node within a ScyllaCluster. +The properties of the Services depend on the selected type. +Additionally, there’s an option to define custom annotations, incorporated into each node’s Service, +which might be useful for further tweaking the Service properties or related objects.

            +
            +

            Headless Type

            +

            For Headless type, Scylla Operator creates a Headless Service with a selector pointing to the particular node in the ScyllaCluster. +Such Service doesn’t provide any additional IP addresses, and the internal DNS record resolves to the PodIP of a node.

            +

            This type of Service is useful when ScyllaCluster nodes broadcast PodIPs to clients and other nodes.

            +

            Example:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +     type: Headless
            +
            +
            +
            +
            +

            ClusterIP Type

            +

            For ClusterIP type, Scylla Operator creates a ClusterIP Service backed by a specific node in the ScyllaCluster.

            +

            These IP addresses are only routable within the same Kubernetes cluster, so it’s a good fit, if you don’t want to expose them to other networks.

            +

            Example:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +     type: ClusterIP
            +
            +
            +
            +
            +

            LoadBalancer Type

            +

            For the LoadBalancer type, Scylla Operator generates a LoadBalancer Service that directs traffic to a specific node within the ScyllaCluster. +On platforms with support for external load balancers, this Service provisions one. +The accessibility of this load balancer’s address depends on the platform and any customizations made; in some cases it may be reachable from the internal network or public Internet.

            +

            Customizations are usually managed via Service annotations, key-value pairs provided in annotations field are merged into each Service object. +LoadBalancer Services should be configured to pass through entire traffic.
            +For example, to expose LoadBalancer only to internal network use the following annotations:

            +
            + +
            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +     type: LoadBalancer
            +     annotations:
            +       service.beta.kubernetes.io/aws-load-balancer-scheme: internal
            +       service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
            +
            +
            +
            + +
            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +     type: LoadBalancer
            +     annotations:
            +       networking.gke.io/load-balancer-type: Internal
            +
            +
            +
            +
            +

            Check platform-specific documentation regarding LoadBalancer configuration to learn more about available options.

            +

            LoadBalancer Service is a superset of ClusterIP Service, implying that each LoadBalancer Service also contains an allocated ClusterIP. +They can be configured using the following fields, which propagate to every node Service:

            +
              +
            • externalTrafficPolicy

            • +
            • internalTrafficPolicy

            • +
            • loadBalancerClass

            • +
            • allocateLoadBalancerNodePorts

            • +
            +

            Check Kubernetes Service documentation to learn more about these options.

            +

            Example:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +     type: LoadBalancer
            +     loadBalancerClass: my-custom-load-balancer-class
            +
            +
            +
            +
            +
            +
            +

            Broadcast Options

            +

            Broadcast options control what is the source of the address being broadcasted to clients and nodes. +It’s configured independently for clients and nodes because you may want to expose these two types of traffic on different networks. +Using different networks can help manage costs, reliability, latency, security policies or other metrics you care about.

            +
            +

            PodIP Type

            +

            Address broadcasted to clients/nodes is taken from Pod. +By default, the address is taken from Pod’s status.PodIP field. +Because a Pod can use multiple address, you may want to provide source options by specifying podIP.source.

            +

            Example:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    broadcastOptions:
            +       clients:
            +         type: PodIP
            +         podIP:
            +           source: Status
            +
            +
            +
            +
            +

            ServiceClusterIP Type

            +

            Address broadcasted to clients or nodes is taken from spec.ClusterIP field of a node’s dedicated Service.

            +

            In order to configure it, the nodeService template must specify a Service having a ClusterIP assigned.

            +

            Example:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    broadcastOptions:
            +       clients:
            +         type: ServiceClusterIP
            +
            +
            +
            +
            +

            ServiceLoadBalancerIngress Type

            +

            Address broadcasted to clients/nodes is taken from the node dedicated Service, from status.ingress[0].ipAddress or status.ingress[0].hostname field.

            +

            In order to configure it, the nodeService template must specify the LoadBalancer Service.

            +

            Example:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    broadcastOptions:
            +       clients:
            +         type: ServiceLoadBalancerIngress
            +         podIP:
            +           source: Status
            +
            +
            +
            +
            +
            +
            +

            Deployment Examples

            +

            The following section contains several specific examples of various network scenarios and explains how nodes and clients communicate with one another.

            +
            +

            In-cluster only

            +

            ScyllaCluster definition:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +      type: ClusterIP
            +    broadcastOptions:
            +      clients:
            +        type: ServiceClusterIP
            +      nodes:
            +        type: ServiceClusterIP
            +
            +
            +

            Both client and nodes are deployed within the same Kubernetes cluster. +They talk through ClusterIP addresses taken from the Service. +Because ClusterIP Services are only routable within the same Kubernetes cluster, this cluster won’t be reachable from outside.

            +

            ClusterIPs

            +
            +
            +

            In-cluster node-to-node, VPC clients-to-nodes

            +

            ScyllaCluster definition:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +      type: ClusterIP
            +    broadcastOptions:
            +      clients:
            +        type: PodIP
            +      nodes:
            +        type: ServiceClusterIP
            +
            +
            +

            In this scenario, we assume that the Pod IP subnet is routable within a VPC. +Clients within the VPC network can communicate directly with ScyllaCluster nodes using PodIPs. +Nodes communicate with each other exclusively within the same Kubernetes cluster.

            +

            PodIPs

            +
            +
            +

            Multi VPC

            +

            ScyllaCluster definition:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +      type: Headless
            +    broadcastOptions:
            +      clients:
            +        type: PodIP
            +      nodes:
            +        type: PodIP
            +
            +
            +

            In this scenario, we set up two separate Kubernetes clusters in distinct VPCs. +These VPCs are interconnected to facilitate inter-VPC connectivity. +We operate on the assumption that the Pod IP subnet is routable within each VPC.

            +

            Both ScyllaClusters use the same exposeOptions, nodes broadcast their Pod IP addresses, enabling them to establish connections with one another. +****Check other documentation pages to know how to connect two ScyllaClusters into one logical cluster.

            +

            Clients, whether deployed within the same Kubernetes cluster or within a VPC, have the capability to reach nodes using their Pod IPs. +Since there is no requirement for any address other than the Pod IP, the Headless service type is sufficient.

            +

            MultiVPC

            +
            +
            +

            Internet

            +

            ScyllaCluster definition:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +      type: LoadBalancer
            +    broadcastOptions:
            +      clients:
            +        type: ServiceLoadBalancerIngress
            +      nodes:
            +        type: ClusterIP 
            +
            +
            +

            We assume that a Kubernetes cluster has been deployed in a cloud provider environment that supports external load balancers. +By specifying the LoadBalancer type in the nodeService template, the Scylla Operator generates a dedicated LB Service for each node. +The cloud provider then establishes an external load balancer with an internet-accessible address. +ScyllaDB nodes broadcast this external address to clients, enabling drivers to connect and discover other nodes. +Since all ScyllaDB nodes reside within the same Kubernetes cluster, there is no need to route traffic through the internet. +Consequently, the nodes are configured to communicate via ClusterIP, which is also accessible within LoadBalancer Services.

            +

            Internet

            +
            +

            Other more complex scenarios can be built upon these simple ones.

            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/generic.html b/v1.11/generic.html new file mode 100644 index 00000000000..d1022f71ae7 --- /dev/null +++ b/v1.11/generic.html @@ -0,0 +1,946 @@ + + + + + + + + + + + + + Deploying Scylla on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Deploying Scylla on a Kubernetes Cluster

            +

            This is a guide to deploy a Scylla Cluster in a generic Kubernetes environment, meaning that Scylla will not be deployed with the ideal performance. +Scylla performs the best when it has fast disks and direct access to the cpu. +This requires some extra setup, which is platform-specific. +For specific configuration and setup, check for details about your particular environment:

            + +
            +

            Prerequisites

            + +
            +
            +

            Running locally

            +

            Running kubernetes locally is a daunting and error prone task. +Fortunately there are ways to make life easier and Minikube makes it a breeze.

            +

            We need to give minikube a little bit more resources than default so start minikube like this:

            +
            minikube start --cpus=6
            +
            +
            +

            Then make kubectl aware of this local installation like this:

            +
            eval $(minikube docker-env)
            +
            +
            +
            +
            +

            Download Scylla Operator

            +

            In this guide you will be using the examples and manifests from Scylla Operator repository, so start off by cloning it to your local machine.

            +
            git clone git@github.com:scylladb/scylla-operator.git
            +cd scylla-operator
            +
            +
            +
            +
            +

            Deploy Cert Manager

            +

            First deploy Cert Manager, you can either follow upsteam instructions or use following command:

            +
            kubectl apply -f examples/common/cert-manager.yaml
            +
            +
            +

            This will install Cert Manager to provision a self-signed certificate.

            +

            Once it’s deployed, wait until Cert Manager is ready:

            +
            kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io
            +kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook
            +
            +
            +
            +
            +

            Deploy Scylla Operator

            +

            Deploy the Scylla Operator using the following commands:

            +
            kubectl apply -f examples/common/operator.yaml
            +
            +
            +

            This will install the operator in namespace scylla-operator. +Wait until it’s ready:

            +
            kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
            +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
            +
            +
            +

            If you want to check the logs of the operator you can do so with:

            +
            kubectl -n scylla-operator logs deployment.apps/scylla-operator
            +
            +
            +
            +
            +

            Create and Initialize a Scylla Cluster

            +

            Now that the operator is running, we can create an instance of a Scylla cluster by creating an instance of the clusters.scylla.scylladb.com resource. +Some of that resource’s values are configurable, so feel free to browse cluster.yaml and tweak the settings to your liking. +Full details for all the configuration options can be found in the Scylla Cluster CRD documentation.

            +

            When you are ready to create a Scylla cluster, simply run:

            +
            kubectl create -f examples/generic/cluster.yaml
            +
            +
            +

            We can verify that a Kubernetes object has been created that represents our new Scylla cluster with the command below. +This is important because it shows that has successfully extended Kubernetes to make Scylla clusters a first class citizen in the Kubernetes cloud-native environment.

            +
            kubectl -n scylla get ScyllaCluster
            +
            +
            +

            Checking the pods that are created is as easy as:

            +
            kubectl -n scylla get pods
            +
            +
            +

            The output should be something like:

            +
            NAME                                    READY   STATUS    RESTARTS   AGE
            +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          9m49s
            +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          7m43s
            +simple-cluster-us-east-1-us-east-1a-2   2/2     Running   0          6m46s
            +
            +
            +

            It is important to note that the operator creates these instances according to a pattern. +This pattern is as follows: CLUSTER_NAME-DATACENTER_NAME-RACK_NAME-INSTANCE_NUMBER as specified in cluster.yaml.

            +

            In the above example we have the following properties:

            +
              +
            • CLUSTER_NAME: simple-cluster

            • +
            • DATACENTER_NAME: us-east-1

            • +
            • RACK_NAME: us-east-1a

            • +
            • INSTANCE_NUMBER: An automatically generated number attached to the pod name.

            • +
            +

            We picked the names to resemble something you can find in a cloud service but this is inconsequential, they can be set to anything you want.

            +

            To check if all the desired members are running, you should see the same number of entries from the following command as the number of members that was specified in cluster.yaml:

            +
            kubectl -n scylla get pod -l app=scylla
            +
            +
            +

            You can also track the state of a Scylla cluster from its status. To check the current status of a Cluster, run:

            +
            kubectl -n scylla describe ScyllaCluster simple-cluster
            +
            +
            +

            Checking the logs of the running scylla instances can be done like this:

            +
            kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 scylla
            +
            +
            +
            +

            Configure host networking

            +

            To squeeze the most out of your deployment it is sometimes necessary to employ host networking. +To enable this the CRD allows for specifying a network parameter as such:

            +
            version: 4.0.0
            +  agentVersion: 2.0.2
            +  cpuset: true
            +  network:
            +    hostNetworking: true
            +
            +
            +

            This will result in hosts network to be used for the Scylla Stateful Set deployment.

            +
            +
            +

            Configure container kernel parameters

            +

            Sometimes it is necessary to run the container with different kernel parameters. +In order to support this, the Scylla Operator defines a cluster property sysctls that is a list of the desired key-value pairs to set.

            +

            For example: To increase the number events available for asynchronous IO processing in the Linux kernel to N set sysctls tofs.aio-max-nr=N.

            +
            spec:
            +  sysctls:
            +  - "fs.aio-max-nr=2097152"
            +
            +
            +
            +
            +

            Deploying Alternator

            +

            The operator is also capable of deploying Alternator instead of the regular Scylla. +This requires a small change in the cluster definition. +Change the cluster.yaml file from this:

            +
            spec:
            +  version: 4.0.0
            +  agentVersion: 2.0.2
            +  developerMode: true
            +  datacenter:
            +    name: us-east-1
            +
            +
            +

            to this:

            +
            spec:
            +  version: 4.0.0
            +  alternator:
            +    port: 8000
            +    writeIsolation: only_rmw_uses_lwt
            +  agentVersion: 2.0.2
            +  developerMode: true
            +  datacenter:
            +    name: us-east-1
            +
            +
            +

            You can specify whichever port you want.

            +

            You must provide desired write isolation, supported values are: “always”, “forbid_rmw”, “only_rmw_uses_lwt”. +Difference between those isolation levels can be found in Scylla Alternator documentation.

            +

            Once this is done the regular CQL ports will no longer be available, the cluster is a pure Alternator cluster.

            +
            +
            +
            +

            Accessing the Database

            +
              +
            • From kubectl:

            • +
            +

            To get a cqlsh shell in your new Cluster:

            +
            kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- cqlsh
            +> DESCRIBE KEYSPACES;
            +
            +
            +
              +
            • From inside a Pod:

            • +
            +

            When you create a new Cluster, automatically creates a Service for the clients to use in order to access the Cluster. +The service’s name follows the convention <cluster-name>-client. +You can see this Service in your cluster by running:

            +
            kubectl -n scylla describe service simple-cluster-client
            +
            +
            +

            Pods running inside the Kubernetes cluster can use this Service to connect to Scylla. +Here’s an example using the Python Driver:

            +
            from cassandra.cluster import Cluster
            +
            +cluster = Cluster(['simple-cluster-client.scylla.svc'])
            +session = cluster.connect()
            +
            +
            +

            If you are running the Alternator you can access the API on the port you specified using plain http.

            +
            +
            +

            Configure Scylla

            +

            The operator can take a ConfigMap and apply it to the scylla.yaml configuration file. +This is done by adding a ConfigMap to Kubernetes and refering to this in the Rack specification. +The ConfigMap is just a file called scylla.yaml that has the properties you want to change in it. +The operator will take the default properties for the rest of the configuration.

            +
              +
            • Create a ConfigMap the default name that the operator uses is scylla-config:

            • +
            +
            kubectl create configmap scylla-config -n scylla --from-file=/path/to/scylla.yaml
            +
            +
            +
              +
            • Wait for the mount to propagate and then restart the cluster:

            • +
            +
            kubectl rollout restart -n scylla statefulset/simple-cluster-us-east-1-us-east-1a
            +
            +
            +
              +
            • The new config should be applied automatically by the operator, check the logs to be sure.

            • +
            +

            Configuring cassandra-rackdc.properties is done by adding the file to the same mount as scylla.yaml.

            +
            kubectl create configmap scylla-config -n scylla --from-file=/tmp/scylla.yaml --from-file=/tmp/cassandra-rackdc.properties -o yaml --dry-run | kubectl replace -f -
            +
            +
            +

            The operator will then apply the overridable properties prefer_local and dc_suffix if they are available in the provided mounted file.

            +
            +

            Note

            +

            If you want to enable authentication, you first need to adjust system_auth keyspace replication factor to the number of nodes in the datacenter via cqlsh. It allows you to ensure that the user’s information is kept highly available for the cluster. If system_auth is not equal to the number of nodes and a node fails, the user whose information is on that node will be denied access. +For production environments only use NetworkTopologyStrategy.

            +
            kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : <replication_factor>};"
            +
            +
            +

            You can read more about enabling authentication in the Enable authentication section of ScyllaDB’s documentation.

            +
            +
            +
            +

            Configure Scylla Manager Agent

            +

            The operator creates a second container for each scylla instance that runs Scylla Manager Agent. +This container serves as a sidecar and it’s the main endpoint for interacting with Scylla API. +The Scylla Manager Agent can be configured with various things such as the security token used to allow access to Scylla API and storage providers for backups.

            +

            To configure the agent you just create a new secret called scylla-agent-config-secret and populate it with the contents in the scylla-manager-agent.yaml file like this:

            +
            kubectl create secret -n scylla generic scylla-agent-config-secret --from-file scylla-manager-agent.yaml
            +
            +
            +

            See Scylla Manager Agent configuration for a complete reference of the Scylla Manager agent config file.

            +
            +

            Scylla Manager Agent auth token

            +

            Operator provisions Agent auth token by copying value from user provided config secret or auto generates it if it’s empty. +To check which value is being used, decode content of <cluster-name>-auth-token secret. +To change it simply remove the secret. Operator will create a new one. To pick up the change in the cluster, initiate a rolling restart.

            +
            +
            +
            +

            Set up monitoring

            +

            To set up monitoring using Prometheus and Grafana follow this guide.

            +
            +
            +

            Scale a ScyllaCluster

            +

            The operator supports adding new nodes to existing racks, adding new racks to the cluster, as well as removing both single nodes and entire racks. To introduce the changes, edit the cluster with:

            +
            kubectl -n scylla edit scyllaclusters.scylla.scylladb.com/simple-cluster
            +
            +
            +
              +
            • To modify the number of nodes in a rack, update the members field of the selected rack to a desired value.

            • +
            • To add a new rack, append it to the .spec.datacenter.racks list. Remember to choose a unique rack name for the new rack.

            • +
            • To remove a rack, first scale it down to zero nodes, and then remove it from .spec.datacenter.racks list.

            • +
            +

            Having edited and saved the yaml, you can check your cluster’s Status and Events to retrieve information about what’s happening:

            +
            kubectl -n scylla describe scyllaclusters.scylla.scylladb.com/simple-cluster
            +
            +
            +
            +

            Note

            +

            If you have configured ScyllaDB with authenticator set to PasswordAuthenticator, you need to manually configure the replication factor of the system_auth keyspace with every scaling operation.

            +
            kubectl -n scylla exec -it pods/simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -u <username> -p <password> -e "ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'us-east-1' : <new_replication_factor>};"
            +
            +
            +

            It is recommended to set system_auth replication factor to the number of nodes in each datacenter.

            +
            +
            +
            +

            Benchmark with cassandra-stress

            +

            After deploying our cluster along with the monitoring, we can benchmark it using cassandra-stress and see its performance in Grafana. We have a mini cli that generates Kubernetes Jobs that run cassandra-stress against a cluster.

            +
            +

            Because cassandra-stress doesn’t scale well to multiple cores, we use multiple jobs with a small core count for each

            +
            +
            # Run a benchmark with 10 jobs, with 6 cpus and 50.000.000 operations each.
            +# Each Job will throttle throughput to 30.000 ops/sec for a total of 300.000 ops/sec.
            +hack/cass-stress-gen.py --num-jobs=10 --cpu=6 --memory=20G --ops=50000000 --limit=30000
            +kubectl apply -f scripts/cassandra-stress.yaml
            +
            +
            +

            Make sure you set the proper arguments in case you have altered things such as name or namespace.

            +
            ./hack/cass-stress-gen.py -h
            +usage: cass-stress-gen.py [-h] [--num-jobs NUM_JOBS] [--name NAME] [--namespace NAMESPACE] [--scylla-version SCYLLA_VERSION] [--host HOST] [--cpu CPU] [--memory MEMORY] [--ops OPS] [--threads THREADS] [--limit LIMIT]
            +                          [--connections-per-host CONNECTIONS_PER_HOST] [--print-to-stdout] [--nodeselector NODESELECTOR]
            +
            +Generate cassandra-stress job templates for Kubernetes.
            +
            +optional arguments:
            +  -h, --help            show this help message and exit
            +  --num-jobs NUM_JOBS   number of Kubernetes jobs to generate - defaults to 1
            +  --name NAME           name of the generated yaml file - defaults to cassandra-stress
            +  --namespace NAMESPACE
            +                        namespace of the cassandra-stress jobs - defaults to "default"
            +  --scylla-version SCYLLA_VERSION
            +                        version of scylla server to use for cassandra-stress - defaults to 4.0.0
            +  --host HOST           ip or dns name of host to connect to - defaults to scylla-cluster-client.scylla.svc
            +  --cpu CPU             number of cpus that will be used for each job - defaults to 1
            +  --memory MEMORY       memory that will be used for each job in GB, ie 2G - defaults to 2G * cpu
            +  --ops OPS             number of operations for each job - defaults to 10000000
            +  --threads THREADS     number of threads used for each job - defaults to 50 * cpu
            +  --limit LIMIT         rate limit for each job - defaults to no rate-limiting
            +  --connections-per-host CONNECTIONS_PER_HOST
            +                        number of connections per host - defaults to number of cpus
            +  --print-to-stdout     print to stdout instead of writing to a file
            +  --nodeselector NODESELECTOR
            +                        nodeselector limits cassandra-stress pods to certain nodes. Use as a label selector, eg. --nodeselector role=scylla
            +
            +
            +

            While the benchmark is running, open up Grafana and take a look at the monitoring metrics.

            +

            After the Jobs finish, clean them up with:

            +
            kubectl delete -f scripts/cassandra-stress.yaml
            +
            +
            +
            +
            +

            Clean Up

            +

            To clean up all resources associated with this walk-through, you can run the commands below.

            +

            NOTE: this will destroy your database and delete all of its associated data.

            +
            kubectl delete -f examples/generic/cluster.yaml
            +kubectl delete -f examples/common/operator.yaml
            +kubectl delete -f examples/common/cert-manager.yaml
            +
            +
            +
            +
            +

            Troubleshooting

            +

            If the cluster does not come up, the first step would be to examine the operator’s logs:

            +
            kubectl -n scylla-operator logs deployment.apps/scylla-operator
            +
            +
            +

            If everything looks OK in the operator logs, you can also look in the logs for one of the Scylla instances:

            +
            kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/genindex.html b/v1.11/genindex.html new file mode 100644 index 00000000000..88d430b560f --- /dev/null +++ b/v1.11/genindex.html @@ -0,0 +1,549 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + + + +
            + + + + + +
            + + +
            + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/gke.html b/v1.11/gke.html new file mode 100644 index 00000000000..178eee78383 --- /dev/null +++ b/v1.11/gke.html @@ -0,0 +1,768 @@ + + + + + + + + + + + + + Deploying Scylla on GKE | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Deploying Scylla on GKE

            +

            This guide is focused on deploying Scylla on GKE with maximum performance (without any persistence guarantees). +It sets up the kubelets on GKE nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

            +

            Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

            +
            +

            TL;DR;

            +

            If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

            +
            # Edit according to your preference
            +GCP_USER=$(gcloud config list account --format "value(core.account)")
            +GCP_PROJECT=$(gcloud config list project --format "value(core.project)")
            +GCP_ZONE=us-west1-b
            +
            +# From inside the examples/gke folder
            +cd examples/gke
            +./gke.sh -u "$GCP_USER" -p "$GCP_PROJECT" -z "$GCP_ZONE"
            +
            +# Example:
            +# ./gke.sh -u yanniszark@arrikto.com -p gke-demo-226716 -z us-west1-b
            +
            +
            +
            +

            Warning

            +

            Make sure to pass a ZONE (ex.: us-west1-b) and not a REGION (ex.: us-west1) or it will deploy nodes in each ZONE available in the region.

            +
            +

            After you deploy, see how you can benchmark your cluster with cassandra-stress.

            +
            +
            +

            Walkthrough

            +
            +

            Google Kubernetes Engine Setup

            +
            +

            Configure environment variables

            +

            First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

            +
            GCP_USER=$( gcloud config list account --format "value(core.account)" )
            +GCP_PROJECT=$( gcloud config list project --format "value(core.project)" )
            +GCP_REGION=us-west1
            +GCP_ZONE=us-west1-b
            +CLUSTER_NAME=scylla-demo
            +CLUSTER_VERSION=$( gcloud container get-server-config --zone ${GCP_ZONE} --format "value(validMasterVersions[0])" )
            +
            +
            +
            +
            +

            Creating a GKE cluster

            +

            First we need to change kubelet CPU Manager policy to static by providing a config file. Create file called systemconfig.yaml with the following content:

            +
            kubeletConfig:
            +  cpuManagerPolicy: static
            +
            +
            +

            Then we’ll create a GKE cluster with the following:

            +
              +
            1. A NodePool of 2 n1-standard-8 Nodes, where the operator and the monitoring stack will be deployed. These are generic Nodes and their free capacity can be used for other purposes.

              +
              gcloud container \
              +clusters create "${CLUSTER_NAME}" \
              +--cluster-version "${CLUSTER_VERSION}" \
              +--node-version "${CLUSTER_VERSION}" \
              +--machine-type "n1-standard-8" \
              +--num-nodes "2" \
              +--disk-type "pd-ssd" --disk-size "20" \
              +--image-type "UBUNTU_CONTAINERD" \
              +--system-config-from-file=systemconfig.yaml \
              +--enable-stackdriver-kubernetes \
              +--no-enable-autoupgrade \
              +--no-enable-autorepair
              +
              +
              +
            2. +
            3. A NodePool of 2 n1-standard-32 Nodes to deploy cassandra-stress later on.

              +
              gcloud container --project "${GCP_PROJECT}" \
              +node-pools create "cassandra-stress-pool" \
              +--cluster "${CLUSTER_NAME}" \
              +--zone "${GCP_ZONE}" \
              +--node-version "${CLUSTER_VERSION}" \
              +--machine-type "n1-standard-32" \
              +--num-nodes "2" \
              +--disk-type "pd-ssd" --disk-size "20" \
              +--node-taints role=cassandra-stress:NoSchedule \
              +--image-type "UBUNTU_CONTAINERD" \
              +--no-enable-autoupgrade \
              +--no-enable-autorepair
              +
              +
              +
            4. +
            5. A NodePool of 4 n1-standard-32 Nodes, where the Scylla Pods will be deployed. Each of these Nodes has 8 local NVMe SSDs attached, which are provided as raw block devices. It is important to disable autoupgrade and autorepair. Automatic cluster upgrade or node repair has a hard timeout after which it no longer respect PDBs and force deletes the Compute Engine instances, which also deletes all data on the local SSDs. At this point, it’s better to handle upgrades manually, with more control over the process and error handling.

              +
              gcloud container \
              +node-pools create "scylla-pool" \
              +--cluster "${CLUSTER_NAME}" \
              +--node-version "${CLUSTER_VERSION}" \
              +--machine-type "n1-standard-32" \
              +--num-nodes "4" \
              +--disk-type "pd-ssd" --disk-size "20" \
              +--local-nvme-ssd-block count="8" \
              +--node-taints role=scylla-clusters:NoSchedule \
              +--node-labels scylla.scylladb.com/node-type=scylla \
              +--image-type "UBUNTU_CONTAINERD" \
              +--no-enable-autoupgrade \
              +--no-enable-autorepair
              +
              +
              +
            6. +
            +
            +
            +

            Setting Yourself as cluster-admin

            +
            +

            (By default GKE doesn’t give you the necessary RBAC permissions)

            +
            +

            Get the credentials for your new cluster

            +
            gcloud container clusters get-credentials "${CLUSTER_NAME}" --zone="${GCP_ZONE}"
            +
            +
            +

            Create a ClusterRoleBinding for your user. +In order for this to work you need to have at least permission container.clusterRoleBindings.create. +The easiest way to obtain this permission is to enable the Kubernetes Engine Admin role for your user in the GCP IAM web interface.

            +
            kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user "${GCP_USER}"
            +
            +
            +
            +
            +
            +

            Prerequisites

            +
            +
            +

            Deploying ScyllaDB Operator

            +

            Refer to Deploying Scylla on a Kubernetes Cluster in the ScyllaDB Operator documentation to deploy the ScyllaDB Operator and its prerequisites.

            +
            +

            Setting up nodes for ScyllaDB

            +

            ScyllaDB, except when in developer mode, requires storage with XFS filesystem. The local NVMes from the cloud provider usually come as individual devices. To use their full capacity together, you’ll first need to form a RAID array from those disks. +NodeConfig performs the necessary RAID configuration and XFS filesystem creation, as well as it optimizes the nodes. You can read more about it in Performance tuning section of ScyllaDB Operator’s documentation.

            +

            Deploy NodeConfig to let it take care of the above operations:

            +
            kubectl apply --server-side -f examples/gke/nodeconfig-alpha.yaml
            +
            +
            +
            +
            +

            Deploying Local Volume Provisioner

            +

            Afterwards, deploy ScyllaDB’s Local Volume Provisioner, capable of dynamically provisioning PersistentVolumes for your ScyllaDB clusters on mounted XFS filesystems, earlier created over the configured RAID0 arrays.

            +
            kubectl -n local-csi-driver apply --server-side -f examples/common/local-volume-provisioner/local-csi-driver/
            +kubectl apply --server-side -f examples/common/local-volume-provisioner/storageclass_xfs.yaml
            +
            +
            +
            +
            +
            +

            Deploy Scylla cluster

            +

            In order for the example to work you need to modify the cluster definition in the following way:

            +
            sed -i "s/<gcp_region>/${GCP_REGION}/g;s/<gcp_zone>/${GCP_ZONE}/g" examples/gke/cluster.yaml
            +
            +
            +

            This will inject your region and zone into the cluster definition so that it matches the kubernetes cluster you just created.

            +
            +
            +

            Deploying ScyllaDB

            +

            Now you can follow the steps described in Deploying Scylla on a Kubernetes Cluster to launch your ScyllaDB cluster in a highly performant environment.

            +
            +

            Accessing the database

            +

            Instructions on how to access the database can also be found in the generic guide.

            +
            +
            +
            +

            Deleting a GKE cluster

            +

            Once you are done with your experiments delete your cluster using the following command:

            +
            gcloud container --project "${GCP_PROJECT}" clusters delete --zone "${GCP_ZONE}" "${CLUSTER_NAME}"
            +
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/helm.html b/v1.11/helm.html new file mode 100644 index 00000000000..7855be10d9f --- /dev/null +++ b/v1.11/helm.html @@ -0,0 +1,916 @@ + + + + + + + + + + + + + Deploying Scylla stack using Helm Charts | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Deploying Scylla stack using Helm Charts

            +

            In this example we will install Scylla stack on Kubernetes. This includes the following components:

            +
              +
            • Scylla Operator

            • +
            • Scylla Manager

            • +
            • Scylla

            • +
            +

            We will use Minikube K8s cluster, but this could be any K8s cluster supported by the Scylla Operator.

            +
            +

            Prerequisites

            +
              +
            • Kubernetes 1.16+

            • +
            • Helm 3+

            • +
            +
            +
            +

            TL;DR

            +
            helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
            +helm repo update
            +kubectl apply -f examples/common/cert-manager.yaml 
            +helm install scylla-operator scylla/scylla-operator --create-namespace --namespace scylla-operator
            +helm install scylla-manager scylla/scylla-manager --create-namespace --namespace scylla-manager
            +helm install scylla scylla/scylla --create-namespace --namespace scylla
            +
            +
            +
            +
            +

            Deploy Cert Manager

            +

            This step is optional if you want to use your own certificate. +If you don’t have one, make sure to not disable autogeneration using Scylla Operator Helm Chart.

            +

            First deploy Cert Manager, you can either follow upsteam instructions or use following command:

            +
            kubectl apply -f examples/common/cert-manager.yaml
            +
            +
            +

            Once it’s deployed, wait until all Cert Manager pods will enter into Running state:

            +
            kubectl wait -n cert-manager --for=condition=ready pod -l app=cert-manager --timeout=60s
            +
            +
            +
            +
            +

            Helm Chart repository

            +

            To install Scylla Helm Chart repository execute the following commands:

            +
            helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
            +helm repo update
            +
            +
            +

            Then you can search through repository, it should contain at least three Helm charts:

            +
            helm search repo scylla
            +NAME                   CHART VERSION   APP VERSION     DESCRIPTION                                       
            +scylla/scylla          1.0.1           v1.0.1          Scylla is a close-to-the-hardware rewrite of Ca...
            +scylla/scylla-manager  1.0.1           v1.0.1          Scylla Manager automates database operations.     
            +scylla/scylla-operator 1.0.1           v1.0.1          Scylla Operator is a Kubernetes Operator for ma...
            +
            +
            +

            All these charts should be installable without any need of customizing (defaults are provided). +Although Helm is used for this particular reason, so lets customize them a bit.

            +
            +
            +

            Scylla Operator Chart

            +

            This chart is very simple, most interesting customizable fields are image, resources and webhook. +All others can be looked up in Chart source in Scylla Operator repository.

            +
            +

            image

            +

            Image allows to define which Scylla Operator image will be used. By default it downloads the image from main +Docker Hub repository, using version defined in Helm Chart. +You can also change pullPolicy if default one does not +fullfill your needs. In Kubernetes documentation you +can read more about different pull policies.

            +

            Image URL will be composed based on these fields in follwing pattern: +repository/scylla-operator:tag

            +
            image:
            +  repository: scylladb
            +  pullPolicy: IfNotPresent
            +  tag: ""
            +
            +
            +
            +
            +

            resources

            +

            You can customize how much resources will be allocated for Operator pods via resource field:

            +
            resources:
            +  limits:
            +    cpu: 100m
            +    memory: 128Mi
            +  requests:
            +    cpu: 100m
            +    memory: 32Mi
            +
            +
            +

            To read more about resource specification, follow Kubernetes documentation.

            +
            +
            +

            webhook

            +

            Webhook field allows to decide whether you want to use autogenerated self-signed certificate using Cert Manager or +whether you want to provide your own certificate.

            +

            createSelfSignedCertificate specifies whether a self-signed certificate should be created using Cert Manager +certificateSecretName: name of a secret containing custom certificate.

            +
            webhook:
            +  createSelfSignedCertificate: true
            +  certificateSecretName: ""
            +
            +
            +
            +
            +

            Customization

            +

            You can customize all these fields and others by providing file containing desired values. +Content of this file will overwrite default values.

            +

            You can find an example in Scylla Operator repository under examples/helm/values.operator.yaml

            +
            +
            +

            Installation

            +

            To deploy Scylla Operator using customized values file execute the following:

            +
            helm install scylla-operator scylla/scylla-operator --values examples/helm/values.operator.yaml --create-namespace --namespace scylla-operator
            +
            +
            +
            +
            +
            +

            Scylla Helm Chart

            +

            Scylla Chart allows to customize and deploy Scylla cluster. +By default Scylla Helm charts deploys working Scylla cluster, but of course we can customize it.

            +
            +

            Customization

            +

            Versions of images used in the cluster can be set via scyllaImage and agentImage

            +
            scyllaImage:
            +  repository: scylladb/scylla
            +  tag: 4.3.0
            +
            +agentImage:
            +  repository: scylladb/scylla-manager-agent
            +  tag: 2.2.1
            +
            +
            +

            A minimal Scylla cluster can be expressed as:

            +
            datacenter: us-east-1
            +racks:
            +- name: us-east-1b
            +  members: 2
            +  storage:
            +    capacity: 5G
            +  resources:
            +    limits:
            +      cpu: 1
            +      memory: 1Gi
            +    requests:
            +      cpu: 1
            +      memory: 1Gi
            +
            +
            +

            Above cluster will use 4.3.0 Scylla, 2.2.1 Scylla Manager Agent sidecar and will have a single rack having 2 nodes. +Each node will have a single CPU and 1 GiB of memory.

            +

            For other customizable fields, please refer to ScyllaCluster CRD definition. +CRD Rack Spec and Helm Chart Rack should have the same fields.

            +
            +
            +

            Installation

            +

            To deploy Scylla cluster using customzied values file execute the following command:

            +
            helm install scylla scylla/scylla --values examples/helm/values.cluster.yaml --create-namespace --namespace scylla
            +
            +
            +

            Scylla Operator will provision this cluster on your K8s environment.

            +
            +
            +
            +

            Scylla Manager Helm Chart

            +

            Scylla Manager Chart allows to customize and deploy Scylla Manager in K8s environment. +Scylla Manager consist of two applications (Scylla Manager itself and Scylla Manager Controller) and additional Scylla cluster.

            +

            To read more about Scylla Manager see Manager guide.

            +
            +

            Scylla Manager

            +

            To set version of used Scylla Manager you can use image field:

            +
            image:
            +  repository: scylladb
            +  pullPolicy: IfNotPresent
            +  tag: 2.2.1
            +
            +
            +

            To control how many resources are allocated for Scylla Manager use resource field:

            +
            resources:
            +  limits:
            +    cpu: 500m
            +    memory: 500Mi
            +  requests:
            +    cpu: 500m
            +    memory: 500Mi
            +
            +
            +
            +
            +

            Scylla Manager Controller

            +

            Similarly Scylla Manager Controller image can be customized:

            +
            controllerImage:
            +  repository: scylladb
            +  pullPolicy: IfNotPresent
            +  tag: ""
            +
            +
            +

            And allocated resources:

            +
            controllerResources:
            +  limits:
            +    cpu: 100m
            +    memory: 30Mi
            +  requests:
            +    cpu: 100m
            +    memory: 20Mi
            +
            +
            +
            +
            +

            Scylla

            +

            To customize internal Scylla instance dedicated to Scylla Manager, see guide above customizing Scylla Helm Chart. +It’s definition should land as a scylla field.

            +
            +
            +

            Customization

            +

            All others customizable fields can be looked up in Chart source in Scylla Operator repository.

            +
            +
            +

            Installation

            +

            To deploy Scylla Manager using customized values file execute the following command:

            +
            helm install scylla-manager scylla/scylla-manager --values examples/helm/values.manager.yaml --create-namespace --namespace scylla-manager
            +
            +
            +
            +
            +
            +

            Results

            +

            Scylla need some time to bootstrap all nodes, but after some time you should be ready to roll. It was simple isn’t it? +You can validate if everything was set up correctly by looking at the all resources created in used namespaces.

            +

            Scylla Operator:

            +
            $ kubectl -n scylla-operator get all
            +
            +NAME                                   READY   STATUS    RESTARTS   AGE
            +pod/scylla-operator-5dbcb54f5c-vjm4m   1/1     Running   0          51s
            +pod/scylla-operator-5dbcb54f5c-wfjbw   1/1     Running   0          51s
            +
            +NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
            +service/scylla-operator-webhook   ClusterIP   10.105.207.130   <none>        443/TCP   51s
            +
            +NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
            +deployment.apps/scylla-operator   2/2     2            2           51s
            +
            +NAME                                         DESIRED   CURRENT   READY   AGE
            +replicaset.apps/scylla-operator-5dbcb54f5c   2         2         2       51s
            +
            +
            +

            Operator is running!

            +

            Scylla Manager:

            +
            $ kubectl -n scylla-manager get all 
            +
            +NAME                                             READY   STATUS    RESTARTS   AGE
            +pod/scylla-manager-669db64dd-bcm4v               1/1     Running   0          89s
            +pod/scylla-manager-controller-844ccc56c4-drbth   1/1     Running   0          89s
            +pod/scylla-manager-controller-844ccc56c4-rhwqx   1/1     Running   0          89s
            +
            +NAME                            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
            +service/scylla-manager          ClusterIP   10.105.231.53   <none>        80/TCP,5090/TCP     89s
            +service/scylla-manager-client   ClusterIP   None            <none>        9180/TCP,5090/TCP   89s
            +
            +NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
            +deployment.apps/scylla-manager              1/1     1            1           89s
            +deployment.apps/scylla-manager-controller   2/2     2            2           89s
            +
            +NAME                                                   DESIRED   CURRENT   READY   AGE
            +replicaset.apps/scylla-manager-669db64dd               1         1         1       89s
            +replicaset.apps/scylla-manager-controller-844ccc56c4   2         2         2       89s
            +
            +
            +

            Good to go, ready to serve!

            +

            Scylla itself:

            +
            $ kubectl -n scylla get all        
            +
            +NAME                                READY   STATUS    RESTARTS   AGE
            +pod/scylla-us-east-1-us-east-1b-0   2/2     Running   0          5m58s
            +pod/scylla-us-east-1-us-east-1b-1   2/2     Running   0          4m29s
            +
            +NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
            +service/scylla-client                   ClusterIP   None           <none>        9180/TCP,5090/TCP                                                 5m59s
            +service/scylla-us-east-1-us-east-1b-0   ClusterIP   10.43.149.92   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   5m58s
            +service/scylla-us-east-1-us-east-1b-1   ClusterIP   10.43.49.0     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   4m29s
            +
            +NAME                                           READY   AGE
            +statefulset.apps/scylla-us-east-1-us-east-1b   2/2     5m59s
            +
            +
            +

            Two running nodes, exactly what we were asking for.

            +
            +
            +

            Monitoring

            +

            To spin up a Prometheus monitoring refer to monitoring guide.

            +

            Helm charts can create ServiceMonitors needed to observe Scylla Managger and Scylla. +Both of these Helm Charts allows to specify whether you want to create a ServiceMonitor:

            +
            serviceMonitor:
            +  create: false
            +
            +
            +

            Change create to true and update your current deployment using:

            +
            helm upgrade --install scylla --namespace scylla scylla/scylla -f examples/helm/values.cluster.yaml
            +
            +
            +

            Helm should notice the difference, install the ServiceMonitor, and then Prometheous will be able to scrape metrics.

            +
            +
            +

            Cleanup

            +

            To remove these applications you can simply uninstall them using Helm CLI:

            +
            helm uninstall scylla -n scylla
            +helm uninstall scylla-manager -n scylla-manager
            +helm uninstall scylla-operator -n scylla-operator
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/index.html b/v1.11/index.html new file mode 100644 index 00000000000..18a76b48cb9 --- /dev/null +++ b/v1.11/index.html @@ -0,0 +1,596 @@ + + + + + + + + + + + + + Scylla Operator Documentation | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Scylla Operator Documentation

            +
            +
            +

            Scylla Operator is an open source project which helps users of Scylla Open Source and Scylla Enterprise run Scylla on Kubernetes (K8s) +The Scylla operator manages Scylla clusters deployed to Kubernetes and automates tasks related to operating a Scylla cluster, like installation, out and downscale, rolling upgrades.

            +_images/logo.png +

            For the latest status of the project, and reports issue, see the Github Project. Also check out the K8s Operator lesson on Scylla University.

            +

            scylla-operator is a Kubernetes Operator for managing Scylla clusters.

            +

            Currently it supports:

            +
              +
            • Deploying multi-zone clusters

            • +
            • Scaling up or adding new racks

            • +
            • Scaling down

            • +
            • Monitoring with Prometheus and Grafana

            • +
            • Integration with Scylla Manager

            • +
            • Dead node replacement

            • +
            • Version Upgrade

            • +
            • Backup

            • +
            • Repairs

            • +
            • Autohealing

            • +
            +

            Choose a topic to begin:

            + +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/manager.html b/v1.11/manager.html new file mode 100644 index 00000000000..1cf7971dea9 --- /dev/null +++ b/v1.11/manager.html @@ -0,0 +1,803 @@ + + + + + + + + + + + + + Deploying Scylla Manager on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Deploying Scylla Manager on a Kubernetes Cluster

            +

            Scylla Manager is a product for database operations automation, +it can schedule tasks such as repairs and backups. +Scylla Manager can manage multiple Scylla clusters and run cluster-wide tasks +in a controlled and predictable way.

            +

            Scylla Manager is available for Scylla Enterprise customers and Scylla Open Source users. +With Scylla Open Source, Scylla Manager is limited to 5 nodes. +See the Scylla Manager Proprietary Software License Agreement for details.

            +
            +

            Prerequisites

            + +
            +
            +

            Architecture

            +

            Scylla Manager in K8s consist of:

            +
              +
            • Dedicated Scylla Cluster

              +

              Scylla Manager persists its state to a Scylla cluster. +Additional small single node cluster is spawned in the Manager namespace.

              +
            • +
            • Scylla Manager Controller

              +

              Main mission of Controller is to watch changes of Scylla Clusters, and synchronize three states.

              +
                +
              1. What user wants - task definition in CRD.

              2. +
              3. What Controller registered - Task name to Task ID mapping - CRD status.

              4. +
              5. Scylla Manager task listing - internal state of Scylla Manager.

              6. +
              +

              When Scylla Cluster CRD is being deployed Controller will register it in Scylla Manager once cluster reaches desired node count. +Once Cluster is fully up and running it will schedule all tasks defined in Cluster CRD. +Controller also supports task updates and unscheduling.

              +
            • +
            • Scylla Manager

              +

              Regular Scylla Manager, the same used in cloud and bare metal deployments.

              +
            • +
            +
            +
            +

            Deploy Scylla Manager

            +

            Deploy the Scylla Manager using the following commands:

            +
            kubectl apply -f examples/common/manager.yaml
            +
            +
            +

            This will install the Scylla Manager in the scylla-manager namespace. +You can check if the Scylla Manager is up and running with:

            +
            kubectl -n scylla-manager get pods
            +NAME                                               READY   STATUS    RESTARTS   AGE
            +scylla-manager-cluster-manager-dc-manager-rack-0   2/2     Running   0          37m
            +scylla-manager-controller-0                        1/1     Running   0          28m
            +scylla-manager-scylla-manager-7bd9f968b9-w25jw     1/1     Running   0          37m
            +
            +
            +

            As you can see there are three pods:

            +
              +
            • scylla-manager-cluster-manager-dc-manager-rack-0 - is a single node Scylla cluster.

            • +
            • scylla-manager-controller-0 - Scylla Manager Controller.

            • +
            • scylla-manager-scylla-manager-7bd9f968b9-w25jw - Scylla Manager.

            • +
            +

            To see if Scylla Manager is fully up and running we can check their logs. +To do this, execute following command:

            +
            kubectl -n scylla-manager logs scylla-manager-controller-0
            +
            +
            +

            The output should be something like:

            +
            {"L":"INFO","T":"2020-09-23T11:25:27.882Z","M":"Scylla Manager Controller started","version":"","build_date":"","commit":"","built_by":"","go_version":"","options":{"Name":"scylla-manager-controller-0","Namespace":"scylla-manager","LogLevel":"debug","ApiAddress":"http://127.0.0.1:5080/api/v1"},"_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
            +{"L":"INFO","T":"2020-09-23T11:25:28.435Z","M":"Registering Components.","_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
            +
            +
            +

            To check logs of Scylla Manager itself, use following command:

            +
            kubectl -n scylla-manager logs scylla-manager-scylla-manager-7bd9f968b9-w25jw
            +
            +
            +

            The output should be something like:

            +
            {"L":"INFO","T":"2020-09-23T11:26:53.238Z","M":"Scylla Manager Server","version":"2.1.2-0.20200816.76cc4dcc","pid":1,"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
            +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Using config","config":{"HTTP":"127.0.0.1:5080","HTTPS":"","TLSCertFile":"/var/lib/scylla-manager/scylla_manager.crt","TLSKeyFile":"/var/lib/scylla-manager/scylla_manager.key","TLSCAFile":"","Prometheus":":56090","PrometheusScrapeInterval":5000000000,"debug":"127.0.0.1:56112","Logger":{"Mode":"stderr","Level":"info","Development":false},"Database":{"Hosts":["scylla-manager-cluster-manager-dc-manager-rack-0.scylla-manager.svc"],"SSL":false,"User":"","Password":"","LocalDC":"","Keyspace":"scylla_manager","MigrateDir":"/etc/scylla-manager/cql","MigrateTimeout":30000000000,"MigrateMaxWaitSchemaAgreement":300000000000,"ReplicationFactor":1,"Timeout":600000000,"TokenAware":true},"SSL":{"CertFile":"","Validate":true,"UserCertFile":"","UserKeyFile":""},"Healthcheck":{"Timeout":250000000,"SSLTimeout":750000000},"Backup":{"DiskSpaceFreeMinPercent":10,"AgeMax":43200000000000},"Repair":{"SegmentsPerRepair":1,"ShardParallelMax":0,"ShardFailedSegmentsMax":100,"PollInterval":200000000,"ErrorBackoff":300000000000,"AgeMax":0,"ShardingIgnoreMsbBits":12}},"config_files":["/mnt/etc/scylla-manager/scylla-manager.yaml"],"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
            +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Checking database connectivity...","_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
            +
            +
            +

            If there are no errors in the logs, let’s spin a Scylla Cluster.

            +
            +
            +

            Cluster registration

            +

            When the Scylla Manager is fully up and running, lets create a regular instance of Scylla cluster.

            +

            See generic tutorial to spawn your cluster.

            +

            Note: If you already have some Scylla Clusters, after installing Manager they should be +automatically registered in Scylla Manager.

            +

            Once cluster reaches desired node count, cluster status will be updated with ID under which it was registered in Manager.

            +
            kubectl -n scylla describe Cluster
            +
            +[...]
            +Status:
            + Manager Id:  d1d532cd-49f2-4c97-9263-25126532803b
            + Racks:
            +   us-east-1a:
            +     Members:        3
            +     Ready Members:  3
            +     Version:        4.0.0
            +
            +
            +

            You can use this ID to talk to Scylla Manager using sctool CLI installed in Scylla Manager Pod. +You can also use Cluster name in namespace/cluster-name format.

            +
            kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
            +
            +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
            +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
            +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
            +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
            +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
            +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
            +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
            +
            +
            +

            Scylla Manager by default registers recurring healhcheck tasks for Agent and for each of the enabled frontends (CQL, Alternator).

            +

            In this task listing we can see CQL and REST healthchecks.

            +
            +
            +

            Task scheduling

            +

            You can either define tasks prior Cluster creation, or for existing Cluster. +Let’s edit already running cluster definition to add repair and backup task.

            +
            kubectl -n scylla edit Cluster simple-cluster
            +
            +
            +

            Add following task definition to Cluster spec:

            +
              repairs:
            +    - name: "users repair"
            +      keyspace: ["users"]
            +      interval: "1d"
            +  backups:
            +    - name: "weekly backup"
            +      location: ["s3:cluster-backups"]
            +      retention: 3
            +      interval: "7d"
            +    - name: "daily backup"
            +      location: ["s3:cluster-backups"]
            +      retention: 7
            +      interval: "1d"
            +
            +
            +

            For full task definition configuration consult Scylla Cluster CRD.

            +

            Note: Scylla Manager Agent must have access to above bucket prior the update in order to schedule backup task. +Consult Scylla Manager documentation for details on how to set it up.

            +

            Scylla Manager Controller will spot this change and will schedule tasks in Scylla Manager.

            +
            kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
            +
            +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
            +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
            +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
            +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
            +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
            +│ backup/275aae7f-c436-4fc8-bcec-479e65fb8372                 │ -L s3:cluster-backups  --retention 3 │ 23 Sep 20 14:28:58 CEST (+7d)  │ NEW    │
            +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
            +│ repair/d4946360-c29d-4bb4-8b9d-619ada495c2a                 │                                      │ 23 Sep 20 14:38:42 CEST        │ NEW    │
            +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
            +
            +
            +

            As you can see, we have two new tasks, weekly recurring backup, and one repair which should start shortly.

            +

            To check progress of run you can use following command:

            +
            kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task progress --cluster d1d532cd-49f2-4c97-9263-25126532803b repair/d4946360-c29d-4bb4-8b9d-619ada495c2a
            +Status:         RUNNING
            +Start time:     23 Sep 20 14:38:42 UTC
            +Duration:       13s
            +Progress:       2.69%
            +Datacenters:
            +  - us-east-1
            ++--------------------+-------+
            +| system_auth        | 8.06% |
            +| system_distributed | 0.00% |
            +| system_traces      | 0.00% |
            ++--------------------+-------+
            +
            +
            +

            Other tasks can be also tracked using the same command, but using different task ID. +Task IDs are present in Cluster Status as well as in task listing.

            +
            +
            +

            Clean Up

            +

            To clean up all resources associated with Scylla Manager, you can run the commands below.

            +

            NOTE: this will destroy your Scylla Manager database and delete all of its associated data.

            +
            kubectl delete -f examples/common/manager.yaml
            +
            +
            +
            +
            +

            Troubleshooting

            +

            Manager is not running

            +

            If the Scylla Manager does not come up, the first step would be to examine the Manager and Controller logs:

            +
            kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-controller
            +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-scylla-manager-7bd9f968b9-w25jw
            +
            +
            +

            My task wasn’t scheduled

            +

            If your task wasn’t scheduled, Cluster status will be updated with error messages for each failed task. +You can also consult Scylla Manager logs.

            +

            Example:

            +

            Following status describes error when backup task cannot be scheduled, due to lack of access to bucket:

            +
            Status:
            +  Backups:
            +    Error:     create backup target: location is not accessible: 10.100.16.62: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.100.16.62 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.107.193.33: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.107.193.33 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.109.197.60: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.109.197.60 and run "scylla-manager-agent check-location -L s3:manager-test --debug"
            +    Id:        00000000-0000-0000-0000-000000000000
            +    Interval:  0
            +    Location:
            +      s3:manager-test
            +    Name:         adhoc backup
            +    Num Retries:  3
            +    Retention:    3
            +    Start Date:   now
            +  Manager Id:     2b9dbe8c-9daa-4703-a66d-c29f63a917c8
            +  Racks:
            +    us-east-1a:
            +      Members:        3
            +      Ready Members:  3
            +      Version:        4.0.0
            +
            +
            +

            Because Controller is infinitely retrying to schedule each defined task, once permission issues will be resolved, +task should appear in task listing and Cluster status.

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/migration.html b/v1.11/migration.html new file mode 100644 index 00000000000..a132ef53fa0 --- /dev/null +++ b/v1.11/migration.html @@ -0,0 +1,740 @@ + + + + + + + + + + + + + Version migrations | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Version migrations

            +
            +

            v0.3.0 -> v1.0.0 migration

            +

            v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common kind +which is easier to disambiguate (ScyllaCluster). +This change is backward incompatible, which means manual migration is needed.

            +

            This procedure involves having two CRDs registered at the same time. We will detach Scylla Pods +from Scylla Operator for a short period to ensure that nothing is garbage collected when Scylla Operator is upgraded. +Compared to the upgrade guide where full deletion is requested, this procedure shouldn’t cause downtimes. +Although detaching resources from their controller is considered hacky. This means that you shouldn’t run procedure +out of the box on production. Make sure this procedure works well multiple times on your staging environment first.

            +

            Read the whole procedure and make sure you understand what is going on before executing any of the commands!

            +

            In case of any issues or questions regarding this procedure, you’re welcomed on our Scylla Users Slack +on #kubernetes channel.

            +
            +
            +

            Procedure

            +
              +
            1. Execute this whole procedure for each cluster sequentially. To get a list of existing clusters execute the following

              +
              kubectl -n scylla get cluster.scylla.scylladb.com
              +
              +NAME             AGE
              +simple-cluster   30m
              +
              +
              +

              All below commands will use scylla namespace and simple-cluster as a cluster name.

              +
            2. +
            3. Make sure you’re using v1.0.0 tag:

              +
              git checkout v1.0.0
              +
              +
              +
            4. +
            5. Upgrade your cert-manager to v1.0.0. If you installed it from a static file from this repo, simply execute the following:

              +
               kubectl apply -f examples/common/cert-manager.yaml
              +
              +
              +

              If your cert-manager was installed in another way, follow official instructions on cert-manager website.

              +
            6. +
            7. examples/common/operator.yaml file contains multiple resources. Extract only CustomResourceDefinition to separate file.

            8. +
            9. Install v1.0.0 CRD definition from file created in the previous step:

              +
              kubectl apply -f examples/common/crd.yaml
              +
              +
              +
            10. +
            11. Save your existing simple-cluster Cluster definition to a file:

              +
              kubectl -n scylla get cluster.scylla.scylladb.com simple-cluster -o yaml > existing-cluster.yaml
              +
              +
              +
            12. +
            13. Migrate Kind and ApiVersion to new values using:

              +
              sed -i 's/scylla.scylladb.com\/v1alpha1/scylla.scylladb.com\/v1/g' existing-cluster.yaml
              +sed -i 's/kind: Cluster/kind: ScyllaCluster/g' existing-cluster.yaml
              +
              +
              +
            14. +
            15. Install migrated CRD instance

              +
              kubectl apply -f existing-cluster.yaml
              +
              +
              +

              At this point, we should have two CRDs describing your Scylla cluster, although the new one is not controlled by the Operator.

              +
            16. +
            17. Get UUID of newly created ScyllaCluster resource:

              +
              kubectl -n scylla get ScyllaCluster simple-cluster --template="{{ .metadata.uid }}"
              +
              +12a3678d-8511-4c9c-8a48-fa78d3992694
              +
              +
              +

              Save output UUID somewhere, it will be referred as <new-cluster-uid> in commands below.

              +

              Depending on your shell, you might get additional ‘%’ sign at the end of UUID, make sure to remove it!

              +
            18. +
            19. Upgrade ClusterRole attached to each of the Scylla nodes to grant them permission to lookup Scylla clusters:

              +
              kubectl patch ClusterRole simple-cluster-member --type "json" -p '[{"op":"add","path":"/rules/-","value":{"apiGroups":["scylla.scylladb.com"],"resources":["scyllaclusters"],"verbs":["get"]}}]'
              +
              +
              +

              Amend role name according to your cluster name, it should look like <scylla-cluster-name>-member.

              +
            20. +
            21. Get a list of all Services associated with your cluster. First get list of all services:

              +
               kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
              +
              + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
              + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          109m
              + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
              + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   108m
              + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   106m
              +
              +
              +
              +
            22. +
            23. For each service, change its ownerReference to point to new CRD instance:

              +
               kubectl -n scylla patch svc <cluster-svc-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
              +
              +
              +

              Replace <cluster-svc-name> with Service name, and <new-cluster-uid> with saved UUID from one of the previous steps.

              +
            24. +
            25. Get a list of all Services again to see if none was deleted. Check also “Age” column, it shouldn’t be lower than previous result.

              +
               kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
              +
              + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
              + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          110m
              + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   110m
              + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
              + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   107m
              +
              +
              +
              +
            26. +
            27. Get a list of StatefulSets associated with your cluster:

              +
              kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
              +
              +NAME                                  READY   AGE
              +simple-cluster-us-east-1-us-east-1a   3/3     104m
              +
              +
              +
            28. +
            29. For each StatefulSet from previous step, change its ownerReference to point to new CRD instance.

              +
               kubectl -n scylla patch sts <cluster-sts-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
              +
              +
              +

              Replace <cluster-sts-name> with StatefulSet name, and <new-cluster-uid> with saved UUID from one of the previous steps.

              +
            30. +
            31. Now when all k8s resources bound to Scylla are attached to new CRD, we can remove 0.3.0 Operator and old CRD definition. +Checkout v0.3.0 version, and remove Scylla Operator, and old CRD:

              +
               git checkout v0.3.0
              + kubectl delete -f examples/generic/operator.yaml
              +
              +
              +
            32. +
            33. Checkout v1.0.0, and install upgraded Scylla Operator:

              +
               git checkout v1.0.0
              + kubectl apply -f examples/common/operator.yaml
              +
              +
              +
            34. +
            35. Wait until Scylla Operator boots up:

              +
               kubectl -n scylla-operator-system wait --for=condition=ready pod --all --timeout=600s
              +
              +
              +
            36. +
            37. Get a list of StatefulSets associated with your cluster:

              +
              kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
              +
              +NAME                                  READY   AGE
              +simple-cluster-us-east-1-us-east-1a   3/3     104m
              +
              +
              +
            38. +
            39. For each StatefulSet from previous step, change its sidecar container image to v1.0.0, and wait until change will be propagated. This step will initiate a rolling restart of pods one by one.

              +
              kubectl -n scylla patch sts <cluster-sts> --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/initContainers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
              +kubectl -n scylla rollout status sts <cluster-sts>
              +
              +
              +

              Replace <cluster-sts-name> with StatefulSet name.

              +
            40. +
            41. If you’re using Scylla Manager, bump Scylla Manager Controller image to v1.0.0

              +
               kubectl -n scylla-manager-system patch sts scylla-manager-controller --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
              +
              +
              +
            42. +
            43. Your Scylla cluster is now migrated to v1.0.0.

            44. +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/monitoring.html b/v1.11/monitoring.html new file mode 100644 index 00000000000..0cea9e153a2 --- /dev/null +++ b/v1.11/monitoring.html @@ -0,0 +1,785 @@ + + + + + + + + + + + + + Monitoring | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Monitoring

            +

            Scylla Operator 1.8 introduced a new API resource ScyllaDBMonitoring, allowing users to deploy a managed monitoring +setup for their Scylla Clusters.

            +
            apiVersion: scylla.scylladb.com/v1alpha1
            +kind: ScyllaDBMonitoring
            +metadata:
            +  name: example
            +spec:
            +  type: Platform
            +  endpointsSelector:
            +    matchLabels:
            +      app.kubernetes.io/name: scylla
            +      scylla-operator.scylladb.com/scylla-service-type: identity
            +      scylla/cluster: replace-with-your-scyllacluster-name
            +  components:
            +    prometheus:
            +      storage:
            +        volumeClaimTemplate:
            +          spec:
            +            resources:
            +              requests:
            +                storage: 1Gi
            +    grafana:
            +      exposeOptions:
            +        webInterface:
            +          ingress:
            +            ingressClassName: haproxy
            +            dnsDomains:
            +            - test-grafana.test.svc.cluster.local
            +            annotations:
            +              haproxy-ingress.github.io/ssl-passthrough: "true"
            +
            +
            +

            For details, refer to the below command:

            +
            $ kubectl explain scylladbmonitorings.scylla.scylladb.com/v1alpha1
            +
            +
            +
            +

            Deploy managed monitoring

            +

            Note: as of v1.8, ScyllaDBMonitoring is experimental. The API is currently in version v1alpha1 and may change in future versions.

            +
            +

            Requirements

            +

            Before you can set up your ScyllaDB monitoring, you need Scylla Operator already installed in your Kubernetes cluster. +For more information on how to deploy Scylla Operator, see:

            + +

            The above example of the monitoring setup also makes use of HAProxy Ingress and Prometheus Operator. +You can deploy them in your Kubernetes cluster using the provided third party examples. If you already have them deployed +in your cluster, you can skip the below steps.

            +
            +

            Deploy Prometheus Operator

            +

            Deploy Prometheus Operator using kubectl:

            +
            $ kubectl -n prometheus-operator apply --server-side -f ./examples/third-party/prometheus-operator
            +
            +
            +
            +
            Wait for Prometheus Operator to roll out
            +
            $ kubectl -n prometheus-operator rollout status --timeout=5m deployments.apps/prometheus-operator
            +deployment "prometheus-operator" successfully rolled out
            +
            +
            +
            +
            +
            +

            Deploy HAProxy Ingress

            +

            Deploy HAProxy Ingress using kubectl:

            +
            $ kubectl -n haproxy-ingress apply --server-side -f ./examples/third-party/haproxy-ingress
            +
            +
            +
            +
            Wait for HAProxy Ingress to roll out
            +
            $ kubectl -n haproxy-ingress rollout status --timeout=5m deployments.apps/haproxy-ingress
            +deployment "haproxy-ingress" successfully rolled out
            +
            +
            +
            +
            +
            +
            +

            Deploy ScyllaDBMonitoring

            +

            First, update the endpointsSelector in examples/monitoring/v1alpha1/scylladbmonitoring.yaml with a label +matching your ScyllaCluster instance name.

            +

            Deploy the monitoring setup using kubectl:

            +
            $ kubectl -n scylla apply --server-side -f ./examples/monitoring/v1alpha1/scylladbmonitoring.yaml
            +
            +
            +

            Scylla Operator will notice the new ScyllaDBMonitoring object, and it will reconcile all necessary resources.

            +
            +

            Wait for ScyllaDBMonitoring to roll out

            +
            $ kubectl wait --for='condition=Progressing=False' scylladbmonitorings.scylla.scylladb.com/example
            +scylladbmonitoring.scylla.scylladb.com/example condition met
            +
            +$ kubectl wait --for='condition=Degraded=False' scylladbmonitorings.scylla.scylladb.com/example
            +scylladbmonitoring.scylla.scylladb.com/example condition met
            +
            +$ kubectl wait --for='condition=Available=True' scylladbmonitorings.scylla.scylladb.com/example
            +scylladbmonitoring.scylla.scylladb.com/example condition met
            +
            +
            +
            +
            +

            Wait for Prometheus to roll out

            +
            $ kubectl rollout status --timeout=5m statefulset.apps/prometheus-example
            +statefulset rolling update complete 1 pods at revision prometheus-example-65b89d55bb...
            +
            +
            +
            +
            +

            Wait for Grafana to roll out

            +
            $ kubectl rollout status --timeout=5m deployments.apps/example-grafana
            +deployment "example-grafana" successfully rolled out
            +
            +
            +
            +
            +
            +

            Accessing Grafana

            +

            For accessing Grafana service from outside the Kubernetes cluster we recommend using an Ingress, although there are many other ways to do so. +When using Ingress, what matters is to direct your packets to the ingress controller Service/Pods and have the correct TLS SNI field set by the caller when reaching out to the service, so it is routed properly, and your client can successfully validate the grafana serving certificate. +This is easier when you are using a real DNS domain that resolves to your Ingress controller’s IP address but most clients and tools allow setting the SNI field manually.

            +
            +
            +

            Prerequisites

            +

            To access Grafana, you first need to collect the serving CA and the credentials.

            +
            $ GRAFANA_SERVING_CERT="$( kubectl -n scylla get secret/example-grafana-serving-ca --template '{{ index .data "tls.crt" }}' | base64 -d )"
            +$ GRAFANA_USER="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "username" }}' | base64 -d )"
            +$ GRAFANA_PASSWORD="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "password" }}' | base64 -d )"
            +
            +
            +
            +
            +

            Connecting through Ingress using a resolvable domain

            +

            In production clusters, the Ingress controller and appropriate DNS records should be set up already. Often there is already a generic wildcard record like *.app.mydomain pointing to the Ingress controller’s external IP. For custom service domains, it is usually a CNAME pointing to the Ingress controller’s A record.

            +

            Note: The ScyllaDBMonitoring example creates an Ingress object with test-grafana.test.svc.cluster.local DNS domain that you should adjust to your domain. Below examples use example-grafana.apps.mydomain.

            +

            Note: To test a resolvable domain from your machine without creating DNS records, you can adjust /etc/hosts or similar.

            +
            $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://example-grafana.apps.mydomain" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
            +200
            +
            +
            +
            +
            +

            Connecting through Ingress using an unresolvable domain

            +

            To connect to an Ingress without a resolvable domain you first need to find out your Ingress controller’s IP that can be resolved externally. Again, there are many ways to do so beyond the below examples.

            +

            Unless stated otherwise, we assume your Ingress is running on port 443.

            +
            $ INGRESS_PORT=443
            +
            +
            +
            +

            Variants

            +
            +
            Ingress ExternalIP
            +

            When you are running in a real cluster there is usually a cloud LoadBalancer or a bare metal alternative providing you with an externally reachable IP address.

            +
            $ INGRESS_IP="$( kubectl -n=haproxy-ingress get service/haproxy-ingress --template='{{ ( index .status.loadBalancer.ingress 0 ).ip }}' )"
            +
            +
            +
            +
            +
            Ingress NodePort
            +

            NodePort is slightly less convenient, but it’s available in development clusters as well.

            +
            $ INGRESS_IP="$( kubectl get nodes --template='{{ $internal_ip := "" }}{{ $external_ip := "" }}{{ range ( index .items 0 ).status.addresses }}{{ if eq .type "InternalIP" }}{{ $internal_ip = .address }}{{ else if eq .type "ExternalIP" }}{{ $external_ip = .address }}{{ end }}{{ end }}{{ if $external_ip }}{{ $external_ip }}{{ else }}{{ $internal_ip }}{{ end }}' )"
            +$ INGRESS_PORT="$( kubectl -n=haproxy-ingress get services/haproxy-ingress --template='{{ range .spec.ports }}{{ if eq .port 443 }}{{ .nodePort }}{{ end }}{{ end }}' )"
            +
            +
            +
            +
            +
            Connection
            +
            $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://test-grafana.test.svc.cluster.local:${INGRESS_PORT}" --resolve "test-grafana.test.svc.cluster.local:${INGRESS_PORT}:${INGRESS_IP}" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
            +200
            +
            +
            +
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/multidc/eks.html b/v1.11/multidc/eks.html new file mode 100644 index 00000000000..b8342fb8f2b --- /dev/null +++ b/v1.11/multidc/eks.html @@ -0,0 +1,769 @@ + + + + + + + + + + + + + Build multiple Amazon EKS clusters with inter-Kubernetes networking | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Build multiple Amazon EKS clusters with inter-Kubernetes networking

            +

            This document describes the process of creating multiple Amazon EKS clusters in different regions, using separate VPCs, and explains the steps necessary for configuring inter-Kubernetes networking between the clusters. +The interconnected clusters can serve as a platform for deploying a multi-datacenter ScyllaDB cluster.

            +

            This guide will walk you through the process of creating and configuring EKS clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference.

            +
            +

            Prerequisites

            +

            To follow the below guide, you first need to install and configure the tools that you will need to create and manage AWS and Kubernetes resources:

            +
              +
            • eksctl – A command line tool for working with EKS clusters.

            • +
            • kubectl – A command line tool for working with Kubernetes clusters.

            • +
            +

            For more information see Getting started with Amazon EKS – eksctl in AWS documentation.

            +
            +
            +

            Create EKS clusters

            +
            +

            Create the first EKS cluster

            +

            Below is the required specification for the first cluster.

            +
            apiVersion: eksctl.io/v1alpha5
            +kind: ClusterConfig
            +
            +metadata:
            +  name: scylladb-us-east-1
            +  region: us-east-1
            +
            +availabilityZones:
            +- us-east-1a
            +- us-east-1b
            +- us-east-1c
            +
            +vpc:
            +  cidr: 10.0.0.0/16
            +
            +nodeGroups:
            +  ...
            +
            +
            +

            Specify the first cluster’s configuration file and save it as cluster-us-east-1.yaml. +Refer to Creating an EKS cluster section of ScyllaDB Operator documentation for the reference of the configuration of node groups.

            +

            To deploy the first cluster, use the below command:

            +
            eksctl create cluster -f=cluster-us-east-1.yaml
            +
            +
            +

            Run the following command to learn the status and VPC ID of the cluster:

            +
            eksctl get cluster --name=scylladb-us-east-1 --region=us-east-1
            +
            +
            +

            You will need to get the cluster’s context for future operations. To do so, use the below command:

            +
            kubectl config current-context
            +
            +
            +

            For any kubectl commands that you will want to run against this cluster, use the --context flag with the value returned by the above command.

            +
            +

            Deploy ScyllaDB Operator

            +

            Once the cluster is ready, refer to Deploying Scylla on a Kubernetes Cluster to deploy the ScyllaDB Operator and its prerequisites.

            +
            +
            +

            Prepare nodes for running ScyllaDB

            +

            Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in Deploying Scylla on EKS in ScyllaDB Operator documentation.

            +
            +
            +
            +

            Create the second EKS cluster

            +

            Below is the required specification for the second cluster. As was the case with the first cluster, the provided values are only exemplary and can be adjusted according to your needs.

            +
            +

            Caution

            +

            It is required that the VPCs of the two EKS clusters have non-overlapping IPv4 network ranges.

            +
            +
            apiVersion: eksctl.io/v1alpha5
            +kind: ClusterConfig
            +
            +metadata:
            +  name: scylladb-us-east-2
            +  region: us-east-2
            +
            +availabilityZones:
            +- us-east-2a
            +- us-east-2b
            +- us-east-2c
            +
            +vpc:
            +  cidr: 172.16.0.0/16
            +
            +nodeGroups:
            +  ...
            +
            +
            +

            Follow analogous steps to create the second EKS cluster and prepare it for running ScyllaDB.

            +
            +
            +
            +

            Configure the network

            +

            The prepared Kubernetes clusters each have a dedicated VPC network. +To be able to route the traffic between the two VPC networks, you need to create a networking connection between them, otherwise known as VPC peering.

            +
            +

            Create VPC peering

            +

            Refer to Create a VPC peering connection in AWS documentation for instructions on creating a VPC peering connection between the two earlier created VPCs.

            +

            In this example, the ID of the created VPC peering connection is pcx-08077dcc008fbbab6.

            +
            +
            +

            Update route tables

            +

            To enable private IPv4 traffic between the instances in the VPC peered network, you need to establish a communication channel by adding a route to the route tables associated with all the subnets associated with the instances for both VPCs. +The destination of the new route in a given route table is the CIDR of the VPC of the other cluster and the target is the ID of the VPC peering connection.

            +

            The following is an example of the route tables that enable communication of instances in two peered VPCs. Each table has a local route and the added route which sends traffic targeted at the other VPC to the peered network connection. The other preconfigured routes are omitted for readability.

            + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            Route tableDestinationTarget
            eksctl-scylladb-us-east-1-cluster/PublicRouteTable10.0.0.0/16local
            172.16.0.0/16pcx-08077dcc008fbbab6
            eksctl-scylladb-us-east-2-cluster/PublicRouteTable172.16.0.0/16local
            10.0.0.0/16pcx-08077dcc008fbbab6
            +

            Refer to Update your route tables for a VPC peering connection in AWS documentation for more information.

            +
            +
            +

            Update security groups

            +

            To allow traffic to flow to and from instances associated with security groups in the peered VPC, you need to update the inbound rules of the VPCs’ shared security groups.

            +

            Below is an example of the inbound rules that to be added to the corresponding security groups of the two VPCs.

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

            Security group name

            Type

            Protocol

            Port range

            Source

            eksctl-scylladb-us-east-1-cluster-ClusterSharedNodeSecurityGroup-TD05V9EVU3B8

            All traffic

            All

            All

            Custom 172.16.0.0/16

            eksctl-scylladb-us-east-2-cluster-ClusterSharedNodeSecurityGroup-1FR9YDLU0VE7M

            All traffic

            All

            All

            Custom 10.0.0.0/16

            +

            The names of the shared security groups of your VPCs should be similar to the ones presented in the example.

            +
            +

            Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters in ScyllaDB Operator documentation for guidance.

            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/multidc/gke.html b/v1.11/multidc/gke.html new file mode 100644 index 00000000000..0b9eb2c1c0e --- /dev/null +++ b/v1.11/multidc/gke.html @@ -0,0 +1,739 @@ + + + + + + + + + + + + + Build multiple GKE clusters with inter-Kubernetes networking | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Build multiple GKE clusters with inter-Kubernetes networking

            +

            This document describes the process of creating multiple GKE clusters in a shared VPC and explains the steps necessary for configuring inter-Kubernetes networking between clusters in different regions. +The interconnected clusters can serve as a platform for deploying a Multi Datacenter ScyllaDB cluster.

            +

            This guide will walk you through the process of creating and configuring GKE clusters in two distinct regions. Although it is only an example setup, it can easily be built upon to create infrastructure tailored to your specific needs. +For simplicity, several predefined values are used throughout the document. The values are only exemplary and can be adjusted to your preference.

            +
            +

            Prerequisites

            +

            To follow the below guide, you first need to install and configure the following tools that you will need to create and manage GCP and Kubernetes resources:

            +
              +
            • gcloud CLI - Google Cloud Command Line Interface, a command line tool for working with Google Cloud resources and services directly.

            • +
            • kubectl – A command line tool for working with Kubernetes clusters.

            • +
            +

            See Install the Google Cloud CLI in GCP documentation and Install Tools in Kubernetes documentation for reference.

            +
            +
            +

            Create and configure a VPC network

            +

            For the clusters to have inter-Kubernetes networking, you will create a virtual network shared between all the instances, with dedicated subnets for each of the clusters. +To create the subnets manually, create the network in custom subnet mode.

            +
            +

            Create the VPC network

            +

            Run the below command to create the network:

            +
            gcloud compute networks create scylladb --subnet-mode=custom
            +
            +
            +

            With the VPC network created, create a dedicated subnet with secondary CIDR ranges for their Pod and Service pools in each region which the clusters will reside in.

            +
            +
            +

            Create VPC network subnets

            +

            To create a subnet for the first cluster in region us-east1, run the below command:

            +
            gcloud compute networks subnets create scylladb-us-east1 \
            +    --region=us-east1 \
            +    --network=scylladb \
            +    --range=10.0.0.0/20 \
            +    --secondary-range='cluster=10.1.0.0/16,services=10.2.0.0/20'
            +
            +
            +

            To create a subnet for the second cluster in region us-west1, run the below command:

            +
            gcloud compute networks subnets create scylladb-us-west1 \
            +    --region=us-west1 \
            +    --network=scylladb \
            +    --range=172.16.0.0/20 \
            +    --secondary-range='cluster=172.17.0.0/16,services=172.18.0.0/20'
            +
            +
            +
            +

            Caution

            +

            It is required that the IPv4 address ranges of the subnets allocated for the GKE clusters do not overlap.

            +
            +

            Refer to Create a VPC-native cluster and Alias IP ranges in GKE documentation for more information about VPC native clusters and alias IP ranges.

            +
            +
            +
            +

            Create GKE clusters

            +

            With the VPC network created, you will now create two VPC native GKE clusters in dedicated regions.

            +
            +

            Create the first GKE cluster

            +

            Run the following command to create the first GKE cluster in the us-east1 region:

            +
            gcloud container clusters create scylladb-us-east1 \
            +    --location=us-east1-b \
            +    --node-locations='us-east1-b,us-east1-c' \
            +    --machine-type=n1-standard-8 \
            +    --num-nodes=1 \
            +    --disk-type=pd-ssd \
            +    --disk-size=20 \
            +    --image-type=UBUNTU_CONTAINERD \
            +    --no-enable-autoupgrade \
            +    --no-enable-autorepair \
            +    --enable-ip-alias \
            +    --network=scylladb \
            +    --subnetwork=scylladb-us-east1 \
            +    --cluster-secondary-range-name=cluster \
            +    --services-secondary-range-name=services
            +
            +
            +

            Refer to Creating a GKE cluster section of ScyllaDB Operator documentation for more information regarding the configuration and deployment of additional node pools, including the one dedicated for ScyllaDB nodes.

            +

            You will need to get the cluster’s context for future operations. To do so, use the below command:

            +
            kubectl config current-context
            +
            +
            +

            For any kubectl commands that you will want to run against this cluster, use the --context flag with the value returned by the above command.

            +
            +

            Deploy ScyllaDB Operator

            +

            Once the cluster is ready, refer to Deploying Scylla on a Kubernetes Cluster to deploy the ScyllaDB Operator and its prerequisites.

            +
            +
            +

            Prepare nodes for running ScyllaDB

            +

            Then, prepare the nodes for running ScyllaDB workloads and deploy a volume provisioner following the steps described in Deploying Scylla on GKE page of the documentation.

            +
            +
            +
            +

            Create the second GKE cluster

            +

            Run the following command to create the second GKE cluster in the us-west1 region:

            +
            gcloud container clusters create scylladb-us-west1 \
            +    --location=us-west1-b \
            +    --node-locations='us-west1-b,us-west1-c' \
            +    --machine-type=n1-standard-8 \
            +    --num-nodes=1 \
            +    --disk-type=pd-ssd \
            +    --disk-size=20 \
            +    --image-type=UBUNTU_CONTAINERD \
            +    --no-enable-autoupgrade \
            +    --no-enable-autorepair \
            +    --enable-ip-alias \
            +    --network=scylladb \
            +    --subnetwork=scylladb-us-west1 \
            +    --cluster-secondary-range-name=cluster \
            +    --services-secondary-range-name=services
            +
            +
            +

            Follow analogous steps to create the second GKE cluster and prepare it for running ScyllaDB.

            +
            +
            +
            +

            Configure the firewall rules

            +

            When creating a cluster, GKE creates several ingress firewall rules that enable the instances to communicate with each other. +To establish interconnectivity between the two created Kubernetes clusters, you will now add the allocated IPv4 address ranges to their corresponding source address ranges.

            +

            First, retrieve the name of the firewall rule associated with the first cluster, which permits traffic between all Pods on a cluster, as required by the Kubernetes networking model. +The rule name is in the following format: gke-[cluster-name]-[cluster-hash]-all.

            +

            To retrieve it, run the below command:

            +
            gcloud compute firewall-rules list --filter='name~gke-scylladb-us-east1-.*-all'
            +
            +
            +

            The output should resemble the following:

            +
            NAME                                NETWORK   DIRECTION  PRIORITY  ALLOW                     DENY  DISABLED
            +gke-scylladb-us-east1-f17db261-all  scylladb  INGRESS    1000      udp,icmp,esp,ah,sctp,tcp        False
            +
            +
            +

            Modify the rule by updating the rule’s source ranges with the allocated Pod IPv4 address ranges of both clusters:

            +
            gcloud compute firewall-rules update gke-scylladb-us-east1-f17db261-all --source-ranges='10.1.0.0/16,172.17.0.0/16'
            +
            +
            +

            Follow the analogous steps for the other cluster. In this example, its corresponding firewall rule name is gke-scylladb-us-west1-0bb60902-all. To update it, you would run:

            +
            gcloud compute firewall-rules update gke-scylladb-us-west1-0bb60902-all --source-ranges='10.1.0.0/16,172.17.0.0/16'
            +
            +
            +

            Refer to Automatically created firewall rules in GKE documentation for more information.

            +
            +

            Having followed the above steps, you should now have a platform prepared for deploying a multi-datacenter ScyllaDB cluster. +Refer to Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters in ScyllaDB Operator documentation for guidance.

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/multidc/index.html b/v1.11/multidc/index.html new file mode 100644 index 00000000000..f1f96bc6f0e --- /dev/null +++ b/v1.11/multidc/index.html @@ -0,0 +1,580 @@ + + + + + + + + + + + + + Deploying multi-datacenter ScyllaDB clusters in Kubernetes | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Deploying multi-datacenter ScyllaDB clusters in Kubernetes

            +

            Prepare a platform for a multi datacenter ScyllaDB cluster deployment:

            +
            +
            + +

            Deploy a multi-datacenter ScyllaDB cluster in Kubernetes:

            +
            +
            + +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/multidc/multidc.html b/v1.11/multidc/multidc.html new file mode 100644 index 00000000000..a0e7b2413a6 --- /dev/null +++ b/v1.11/multidc/multidc.html @@ -0,0 +1,1170 @@ + + + + + + + + + + + + + Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters

            +

            This document describes the process of deploying a Multi Datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters.

            +

            This guide will walk you through the example procedure of deploying two datacenters in distinct regions of a selected cloud provider.

            +
            +

            Note

            +

            This guide is dedicated to deploying multi-datacenter ScyllaDB clusters and does not discuss unrelated configuration options. +For details of ScyllaDB cluster deployments and their configuration, refer to Deploying Scylla on a Kubernetes Cluster in ScyllaDB Operator documentation.

            +
            +
            +

            Prerequisites

            +

            As this document describes the procedure of deploying a Multi Datacenter ScyllaDB cluster, you are expected to have the required infrastructure prepared. +Let’s assume two interconnected Kubernetes clusters, capable of communicating with each other over PodIPs, with each cluster meeting the following requirements:

            +
              +
            • a node pool dedicated to ScyllaDB nodes composed of at least 3 nodes running in different zones (with unique topology.kubernetes.io/zone label), configured to run ScyllaDB, each labeled with scylla.scylladb.com/node-type: scylla

            • +
            • running ScyllaDB Operator and its prerequisites

            • +
            • running a storage provisioner capable of provisioning XFS volumes of StorageClass scylladb-local-xfs in each of the nodes dedicated to ScyllaDB instances

            • +
            +

            You can refer to one of our guides describing the process of preparing such infrastructure:

            + +

            Additionally, to follow the below guide, you need to install and configure the following tools that you will need to manage Kubernetes resources:

            +
              +
            • kubectl – A command line tool for working with Kubernetes clusters.

            • +
            +

            See Install Tools in Kubernetes documentation for reference.

            +
            +
            +

            Multi Datacenter ScyllaDB Cluster

            +

            In v1.11, ScyllaDB Operator introduced support for manual multi-datacenter ScyllaDB cluster deployments.

            +
            +

            Warning

            +

            ScyllaDB Operator only supports manual configuration of multi-datacenter ScyllaDB clusters. +In other words, although ScyllaCluster API exposes the machinery necessary for setting up multi-datacenter ScylaDB clusters, the ScyllaDB Operator only automates operations for a single datacenter.

            +

            Operations related to multiple datacenters may require manual intervention of a human operator. +Most notably, destroying one of the Kubernetes clusters or ScyllaDB datacenters is going to leave DN nodes behind in other datacenters, and their removal has to be carried out manually.

            +
            +

            The main mechanism used to set up a manual multi-datacenter ScyllaDB cluster is a field in ScyllaCluster’s specification - externalSeeds.

            +
            +

            External seeds

            +

            The externalSeeds field in ScyllaCluster’s specification enables control over external seeds that are propagated to ScyllaDB binary as --seed-provider-parameters seeds=<external-seeds>. +In this context, external should be understood as “external to the datacenter being specified by the API”. +The provided seeds are used by the nodes as initial points of contact, which allows them to discover the cluster ring topology when joining it.

            +

            Refer to Scylla Seed Nodes in ScyllaDB documentation for more information regarding the function of seed nodes in ScyllaDB. +For more details regarding the function and implementation of external seeds, refer to the original enhancement proposal.

            +
            +
            +

            Networking

            +

            Since this guide assumes interconnectivity over PodIPs of the Kubernetes clusters, you are going to configure the ScyllaDB cluster’s nodes to communicate over PodIPs. +This is enabled by a subset of exposeOptions specified in ScyllaCluster API, introduced in v1.11.

            +

            For this particular setup, define the ScyllaClusers as follows:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +spec:
            +  exposeOptions:
            +    nodeService:
            +      type: Headless
            +    broadcastOptions:
            +      clients:
            +        type: PodIP
            +      nodes:
            +        type: PodIP
            +
            +
            +

            However, other configuration options allow for the manual deployment of multi-datacenter ScyllaDB clusters in different network setups. For details, refer to Exposing ScyllaClusters in ScyllaDB Operator documentation.

            +
            +

            Deploy a multi-datacenter ScyllaDB Cluster

            +
            +
            +

            Using context

            +

            Let’s specify contexts for kubectl commands used throughout the guide. +To retrieve the context of your current cluster, run:

            +
            kubectl config current-context
            +
            +
            +

            Save the contexts of the two clusters, which you are going to deploy the datacenters in, as CONTEXT_DC1 and CONTEXT_DC2 environment variables correspondingly.

            +
            +
            +

            Deploy the first datacenter

            +

            First, run the below command to create a dedicated ‘scylla’ namespace:

            +
            kubectl --context="${CONTEXT_DC1}" create ns scylla
            +
            +
            +

            For this guide, let’s assume that your cluster is running in us-east-1 region and the nodes dedicated to running ScyllaDB nodes are running in zones us-east-1a, us-east-1b and us-east-1c correspondingly. If that is not the case, adjust the manifest accordingly.

            +
            +

            Caution

            +

            The .spec.name field of the ScyllaCluster objects represents the ScyllaDB cluster name and has to be consistent across all datacenters of this ScyllaDB cluster. +The names of the datacenters, specified in .spec.datacenter.name, have to be unique across the entire multi-datacenter cluster.

            +

            For more information see Create a ScyllaDB Cluster - Multi Data Centers (DC) in ScyllaDB documentation.

            +
            +

            Save the ScyllaCluster manifest in dc1.yaml:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +metadata:
            +  name: scylla-cluster
            +  namespace: scylla
            +spec:
            +  version: 5.2.7
            +  agentVersion: 3.1.2
            +  cpuset: true
            +  sysctls:
            +  - "fs.aio-max-nr=2097152"
            +  automaticOrphanedNodeCleanup: true
            +  exposeOptions:
            +    broadcastOptions:
            +      clients:
            +        type: PodIP
            +      nodes:
            +        type: PodIP
            +    nodeService:
            +      type: Headless
            +  datacenter:
            +    name: us-east-1
            +    racks:
            +    - name: a
            +      members: 1
            +      storage:
            +        storageClassName: scylladb-local-xfs
            +        capacity: 1800G
            +      agentResources:
            +        requests:
            +          cpu: 100m
            +          memory: 250M
            +        limits:
            +          cpu: 100m
            +          memory: 250M
            +      resources:
            +        requests:
            +          cpu: 7
            +          memory: 56G
            +        limits:
            +          cpu: 7
            +          memory: 56G
            +      placement:
            +        podAntiAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +          - topologyKey: kubernetes.io/hostname
            +            labelSelector:
            +              matchLabels:
            +                app.kubernetes.io/name: scylla
            +                scylla/cluster: scylla-cluster
            +        nodeAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +            nodeSelectorTerms:
            +            - matchExpressions:
            +              - key: topology.kubernetes.io/zone
            +                operator: In
            +                values:
            +                - us-east-1a
            +              - key: scylla.scylladb.com/node-type
            +                operator: In
            +                values:
            +                - scylla
            +        tolerations:
            +        - key: role
            +          operator: Equal
            +          value: scylla-clusters
            +          effect: NoSchedule
            +    - name: b
            +      members: 1
            +      storage:
            +        storageClassName: scylladb-local-xfs
            +        capacity: 1800G
            +      agentResources:
            +        requests:
            +          cpu: 100m
            +          memory: 250M
            +        limits:
            +          cpu: 100m
            +          memory: 250M
            +      resources:
            +        requests:
            +          cpu: 7
            +          memory: 56G
            +        limits:
            +          cpu: 7
            +          memory: 56G
            +      placement:
            +        podAntiAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +          - topologyKey: kubernetes.io/hostname
            +            labelSelector:
            +              matchLabels:
            +                app.kubernetes.io/name: scylla
            +                scylla/cluster: scylla-cluster
            +        nodeAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +            nodeSelectorTerms:
            +            - matchExpressions:
            +              - key: topology.kubernetes.io/zone
            +                operator: In
            +                values:
            +                - us-east-1b
            +              - key: scylla.scylladb.com/node-type
            +                operator: In
            +                values:
            +                - scylla
            +        tolerations:
            +        - key: role
            +          operator: Equal
            +          value: scylla-clusters
            +          effect: NoSchedule
            +    - name: c
            +      members: 1
            +      storage:
            +        storageClassName: scylladb-local-xfs
            +        capacity: 1800G
            +      agentResources:
            +        requests:
            +          cpu: 100m
            +          memory: 250M
            +        limits:
            +          cpu: 100m
            +          memory: 250M
            +      resources:
            +        requests:
            +          cpu: 7
            +          memory: 56G
            +        limits:
            +          cpu: 7
            +          memory: 56G
            +      placement:
            +        podAntiAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +          - topologyKey: kubernetes.io/hostname
            +            labelSelector:
            +              matchLabels:
            +                app.kubernetes.io/name: scylla
            +                scylla/cluster: scylla-cluster
            +        nodeAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +            nodeSelectorTerms:
            +            - matchExpressions:
            +              - key: topology.kubernetes.io/zone
            +                operator: In
            +                values:
            +                - us-east-1c
            +              - key: scylla.scylladb.com/node-type
            +                operator: In
            +                values:
            +                - scylla
            +        tolerations:
            +        - key: role
            +          operator: Equal
            +          value: scylla-clusters
            +          effect: NoSchedule
            +
            +
            +

            Apply the manifest:

            +
            kubectl --context="${CONTEXT_DC1}" apply --server-side -f=dc1.yaml
            +
            +
            +

            Wait for the cluster to be fully rolled out:

            +
            kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
            +
            +
            +
            scyllacluster.scylla.scylladb.com/scylla-cluster condition met
            +
            +
            +
            kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
            +
            +
            +
            scyllacluster.scylla.scylladb.com/scylla-cluster condition met
            +
            +
            +
            kubectl --context="${CONTEXT_DC1}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster
            +
            +
            +
            scyllacluster.scylla.scylladb.com/scylla-cluster condition met
            +
            +
            +

            You can now verify that all the nodes of your cluster are in UN state:

            +
            kubectl --context="${CONTEXT_DC1}" -n=scylla exec -it pod/scylla-cluster-us-east-1-a-0 -c=scylla -- nodetool status
            +
            +
            +

            The expected output should look similar to the below:

            +
            Datacenter: us-east-1
            +=====================
            +Status=Up/Down
            +|/ State=Normal/Leaving/Joining/Moving
            +--  Address      Load       Tokens       Owns    Host ID                               Rack
            +UN  10.0.70.195  290 KB     256          ?       494277b9-121c-4af9-bd63-3d0a7b9305f7  c
            +UN  10.0.59.24   559 KB     256          ?       a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37  b
            +UN  10.0.19.237  107 KB     256          ?       64b6292a-327f-4128-852a-6004039f402e  a
            +
            +
            +
            +
            Retrieve PodIPs of ScyllaDB nodes for use as external seeds
            +
            +

            Warning

            +

            Due to the ephemeral nature of PodIPs, it is ill-advised to use them as seeds in production environments. +This is because there is a high likelihood that the Pods of your ScyllaDB clusters will change their IPs during the cluster’s lifecycle, and so the provided seeds will no longer point to the ScyllaDB nodes. +It is undesired, as the seeds provided on node’s startup may serve as fallback contact points when all of the node’s peers are unreachable. +In production environments, it is recommended that you use domain names or non-ephemeral IP addresses as external seeds. +PodIPs are being used in this example for the sheer simplicity of this setup.

            +
            +

            Use the below commands and their expected outputs as a reference for retrieving the PodIPs used by the cluster for inter-node communication.

            +
            kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-a-0 --template='{{ .status.podIP }}'
            +
            +
            +
            10.0.19.237
            +
            +
            +
            kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-b-0 --template='{{ .status.podIP }}'
            +
            +
            +
            10.0.59.24
            +
            +
            +
            kubectl --context="${CONTEXT_DC1}" -n=scylla get pod/scylla-cluster-us-east-1-c-0 --template='{{ .status.podIP }}'
            +
            +
            +
            10.0.70.195
            +
            +
            +

            You are going to utilize the retrieved addresses as seeds for the other datacenter.

            +
            +
            +
            +

            Deploy the second datacenter

            +

            To deploy the second datacenter, you will follow similar steps.

            +

            First, create a dedicated ‘scylla’ namespace:

            +
            kubectl --context="${CONTEXT_DC2}" create ns scylla
            +
            +
            +

            Replace the values in .spec.externalSeeds of the below manifest with the Pod IP addresses that you retrieved earlier. +The provided values are going to serve as initial contact points for the joining nodes of the second datacenter.

            +

            For this guide, let’s assume that the second cluster is running in us-east-2 region and the nodes dedicated for running ScyllaDB nodes are running in zones us-east-2a, us-east-2b and us-east-2c correspondingly. If that is not the case, adjust the manifest accordingly. +Having configured it, save the manifest as dc2.yaml:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +metadata:
            +  name: scylla-cluster
            +  namespace: scylla
            +spec:
            +  version: 5.2.7
            +  agentVersion: 3.1.2
            +  cpuset: true
            +  sysctls:
            +  - "fs.aio-max-nr=2097152"
            +  automaticOrphanedNodeCleanup: true
            +  exposeOptions:
            +    broadcastOptions:
            +      clients:
            +        type: PodIP
            +      nodes:
            +        type: PodIP
            +    nodeService:
            +      type: Headless
            +  externalSeeds:
            +  - 10.0.19.237
            +  - 10.0.59.24
            +  - 10.0.70.195
            +  datacenter:
            +    name: us-east-2
            +    racks:
            +    - name: a
            +      members: 1
            +      storage:
            +        storageClassName: scylladb-local-xfs
            +        capacity: 1800G
            +      agentResources:
            +        requests:
            +          cpu: 100m
            +          memory: 250M
            +        limits:
            +          cpu: 100m
            +          memory: 250M
            +      resources:
            +        requests:
            +          cpu: 7
            +          memory: 56G
            +        limits:
            +          cpu: 7
            +          memory: 56G
            +      placement:
            +        podAntiAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +          - topologyKey: kubernetes.io/hostname
            +            labelSelector:
            +              matchLabels:
            +                app.kubernetes.io/name: scylla
            +                scylla/cluster: scylla-cluster
            +        nodeAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +            nodeSelectorTerms:
            +            - matchExpressions:
            +              - key: topology.kubernetes.io/zone
            +                operator: In
            +                values:
            +                - us-east-2a
            +              - key: scylla.scylladb.com/node-type
            +                operator: In
            +                values:
            +                - scylla
            +        tolerations:
            +        - key: role
            +          operator: Equal
            +          value: scylla-clusters
            +          effect: NoSchedule
            +    - name: b
            +      members: 1
            +      storage:
            +        storageClassName: scylladb-local-xfs
            +        capacity: 1800G
            +      agentResources:
            +        requests:
            +          cpu: 100m
            +          memory: 250M
            +        limits:
            +          cpu: 100m
            +          memory: 250M
            +      resources:
            +        requests:
            +          cpu: 7
            +          memory: 56G
            +        limits:
            +          cpu: 7
            +          memory: 56G
            +      placement:
            +        podAntiAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +          - topologyKey: kubernetes.io/hostname
            +            labelSelector:
            +              matchLabels:
            +                app.kubernetes.io/name: scylla
            +                scylla/cluster: scylla-cluster
            +        nodeAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +            nodeSelectorTerms:
            +            - matchExpressions:
            +              - key: topology.kubernetes.io/zone
            +                operator: In
            +                values:
            +                - us-east-2b
            +              - key: scylla.scylladb.com/node-type
            +                operator: In
            +                values:
            +                - scylla
            +        tolerations:
            +        - key: role
            +          operator: Equal
            +          value: scylla-clusters
            +          effect: NoSchedule
            +    - name: c
            +      members: 1
            +      storage:
            +        storageClassName: scylladb-local-xfs
            +        capacity: 1800G
            +      agentResources:
            +        requests:
            +          cpu: 100m
            +          memory: 250M
            +        limits:
            +          cpu: 100m
            +          memory: 250M
            +      resources:
            +        requests:
            +          cpu: 7
            +          memory: 56G
            +        limits:
            +          cpu: 7
            +          memory: 56G
            +      placement:
            +        podAntiAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +          - topologyKey: kubernetes.io/hostname
            +            labelSelector:
            +              matchLabels:
            +                app.kubernetes.io/name: scylla
            +                scylla/cluster: scylla-cluster
            +        nodeAffinity:
            +          requiredDuringSchedulingIgnoredDuringExecution:
            +            nodeSelectorTerms:
            +            - matchExpressions:
            +              - key: topology.kubernetes.io/zone
            +                operator: In
            +                values:
            +                - us-east-2c
            +              - key: scylla.scylladb.com/node-type
            +                operator: In
            +                values:
            +                - scylla
            +        tolerations:
            +        - key: role
            +          operator: Equal
            +          value: scylla-clusters
            +          effect: NoSchedule
            +
            +
            +

            To apply the manifest, run:

            +
            kubectl --context="${CONTEXT_DC2}" -n=scylla apply --server-side -f=dc2.yaml
            +
            +
            +

            Wait for the second datacenter to roll out:

            +
            kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Progressing=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
            +
            +
            +
            scyllacluster.scylla.scylladb.com/scylla-cluster condition met
            +
            +
            +
            kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Degraded=False' scyllaclusters.scylla.scylladb.com/scylla-cluster
            +
            +
            +
            scyllacluster.scylla.scylladb.com/scylla-cluster condition met
            +
            +
            +
            kubectl --context="${CONTEXT_DC2}" -n=scylla wait --for='condition=Available=True' scyllaclusters.scylla.scylladb.com/scylla-cluster
            +
            +
            +
            scyllacluster.scylla.scylladb.com/scylla-cluster condition met
            +
            +
            +

            You can verify that the nodes have joined the existing cluster and that you are now running a multi-datacenter ScyllaDB cluster by running nodetool status with the below command:

            +
            kubectl --context="${CONTEXT_DC2}" -n=scylla exec -it pod/scylla-cluster-us-east-2-a-0 -c=scylla -- nodetool status
            +
            +
            +
            Datacenter: us-east-1
            +=====================
            +Status=Up/Down
            +|/ State=Normal/Leaving/Joining/Moving
            +--  Address        Load       Tokens       Owns    Host ID                               Rack
            +UN  10.0.70.195    705 KB     256          ?       494277b9-121c-4af9-bd63-3d0a7b9305f7  c
            +UN  10.0.59.24     764 KB     256          ?       a3a98e08-0dfd-4a25-a96a-c5ab2f47eb37  b
            +UN  10.0.19.237    634 KB     256          ?       64b6292a-327f-4128-852a-6004039f402e  a
            +Datacenter: us-east-2
            +=====================
            +Status=Up/Down
            +|/ State=Normal/Leaving/Joining/Moving
            +--  Address        Load       Tokens       Owns    Host ID                               Rack
            +UN  172.16.39.209  336 KB     256          ?       7c30ea55-7a4f-4d93-86f7-c881772ebe62  b
            +UN  172.16.25.18   759 KB     256          ?       665dde7e-e420-4db3-8c54-ca71efd39b2e  a
            +UN  172.16.87.27   503 KB     256          ?       c19c89cb-e24c-4062-9df4-2aa90ab29a99  c
            +
            +
            +
            +
            +
            +
            +

            Scylla Manager

            +

            To integrate a multi-datacenter ScyllaDB cluster with Scylla Manager, you must deploy the Scylla Manager in only one datacenter.

            +

            In this example, let’s choose the Kubernetes cluster deployed in the first datacenter to host it. +To deploy Scylla Manager, follow the steps described in Deploying Scylla Manager on a Kubernetes Cluster +in ScyllaDB Operator documentation.

            +

            In order to define the Scylla Manager tasks, add them to the ScyllaCluster object deployed in the same Kubernetes cluster +in which your Scylla Manager is running.

            +

            Every datacenter (represented by ScyllaCluster CR) is, by default, provisioned with a new, random Scylla Manager Agent auth token. +To use Scylla Manager with multiple datacenter (represented by ScyllaClusters), you have to make sure they all use the same token.

            +

            Extract it from the first datacenter with the below command:

            +
            kubectl --context="${CONTEXT_DC1}" -n=scylla get secrets/scylla-cluster-auth-token --template='{{ index .data "auth-token.yaml" }}' | base64 -d
            +
            +
            +
            auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf
            +
            +
            +

            Save the output, replace the token with your own, and patch the secret in the second datacenter with the below command:

            +
            kubectl --context="${CONTEXT_DC2}" -n=scylla patch secret/scylla-cluster-auth-token--type='json' -p='[{"op": "add", "path": "/stringData", "value": {"auth-token.yaml": "auth_token: 84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf"}}]'
            +
            +
            +

            Execute a rolling restart of the nodes in DC2 to make sure they pick up the new token:

            +
            kubectl --context="${CONTEXT_DC2}" -n=scylla patch scyllacluster/scylla-cluster --type='merge' -p='{"spec": {"forceRedeploymentReason": "sync scylla-manager-agent token ('"$( date )"')"}}'
            +
            +
            +
            +
            +

            ScyllaDBMonitoring

            +

            To monitor your cluster, deploy ScyllaDBMonitoring in every datacenter independently. +To deploy ScyllaDB Monitoring, follow the steps described in Deploy managed monitoring in ScyllaDB Operator documentation.

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/nodeoperations/automatic-cleanup.html b/v1.11/nodeoperations/automatic-cleanup.html new file mode 100644 index 00000000000..4927fce6a83 --- /dev/null +++ b/v1.11/nodeoperations/automatic-cleanup.html @@ -0,0 +1,577 @@ + + + + + + + + + + + + + Automatic cleanup and replacement in case when k8s node is lost | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Automatic cleanup and replacement in case when k8s node is lost

            +

            In case when your k8s cluster loses one of the nodes due to incident or explicit removal, Scylla Pods may become unschedulable due to PVC node affinity.

            +

            When automaticOrphanedNodeCleanup flag is enabled in your ScyllaCluster, Scylla Operator will perform automatic +node replacement of a Pod which lost his bound resources.

            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/nodeoperations/index.html b/v1.11/nodeoperations/index.html new file mode 100644 index 00000000000..4e741fc1d58 --- /dev/null +++ b/v1.11/nodeoperations/index.html @@ -0,0 +1,577 @@ + + + + + + + + + + + + + Node operations using Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Node operations using Scylla Operator

            +
            +
            +

            Choose a topic:

            + +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/nodeoperations/maintenance-mode.html b/v1.11/nodeoperations/maintenance-mode.html new file mode 100644 index 00000000000..534467acc89 --- /dev/null +++ b/v1.11/nodeoperations/maintenance-mode.html @@ -0,0 +1,586 @@ + + + + + + + + + + + + + Maintenance mode | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Maintenance mode

            +

            When maintenance mode is enabled, readiness probe of Scylla Pod will always return failure and liveness probe will always succeed. This causes that Pod under maintenance +is being removed from K8s Load Balancer and DNS registry but Pod itself stays alive.

            +

            This allows the Scylla Operator to interact with Scylla and Scylla dependencies inside the Pod. +For example user may turn off Scylla process, do something with the filesystem and bring the process back again.

            +

            To enable maintenance mode add scylla/node-maintenance label to service in front of Scylla Pod.

            +
            kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance=""
            +
            +
            +

            To disable, simply remove this label from service.

            +
            kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance-
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/nodeoperations/replace-node.html b/v1.11/nodeoperations/replace-node.html new file mode 100644 index 00000000000..45a22bad993 --- /dev/null +++ b/v1.11/nodeoperations/replace-node.html @@ -0,0 +1,660 @@ + + + + + + + + + + + + + Replacing a Scylla node | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Replacing a Scylla node

            +
            +

            Replacing a dead node

            +

            In the case of a host failure, it may not be possible to bring back the node to life.

            +

            Replace dead node operation will cause the other nodes in the cluster to stream data to the node that was replaced. +This operation can take some time (depending on the data size and network bandwidth).

            +

            This procedure is for replacing one dead node. To replace more than one dead node, run the full procedure to completion one node at a time

            +

            Procedure

            +
              +
            1. Verify the status of the node using nodetool status command, the node with status DN is down and need to be replaced

              +
              kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
              +Datacenter: us-east-1
              +=====================
              +Status=Up/Down
              +|/ State=Normal/Leaving/Joining/Moving
              +--  Address        Load       Tokens       Owns    Host ID                               Rack
              +UN  10.43.125.110  74.63 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
              +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
              +DN  10.43.43.51    74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
              +
              +
              +
            2. +
            3. Identify service which is bound to down node by checking IP address

              +
              kubectl -n scylla get svc
              +NAME                                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                           AGE
              +simple-cluster-client                   ClusterIP   None            <none>        9180/TCP                                                          3h12m
              +simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.231.189   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h12m
              +simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.125.110   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h11m
              +simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.43.51     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h5m
              +
              +
              +
            4. +
            5. Drain node which we would like to replace using. This command may delete your data from local disks attached to given node!

              +
              kubectl drain gke-scylla-demo-default-pool-b4b390a1-6j12 --ignore-daemonsets --delete-local-data
              +
              +
              +

              Pod which will be replaced should enter the Pending state

              +
              kubectl -n scylla get pods
              +NAME                                    READY   STATUS    RESTARTS   AGE
              +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h21m
              +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h19m
              +simple-cluster-us-east-1-us-east-1a-2   0/2     Pending   0          8m14s
              +
              +
              +
            6. +
            7. To being node replacing, add scylla/replace="" label to service bound to pod we are replacing.

              +
              kubectl -n scylla label svc simple-cluster-us-east-1-us-east-1a-2 scylla/replace=""
              +
              +
              +

              Your failed Pod should be recreated on available k8s node

              +
              kubectl -n scylla get pods
              +NAME                                    READY   STATUS    RESTARTS   AGE
              +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h27m
              +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h25m
              +simple-cluster-us-east-1-us-east-1a-2   1/2     Running   0          9s
              +
              +
              +

              Because other nodes in cluster must stream data to new node this operation might take some time depending on how much data your cluster stores. +After bootstraping is over, your new Pod should be ready to go. +Old one shouldn’t be no longer visible in nodetool status

              +
              kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
              +Datacenter: us-east-1
              +=====================
              +Status=Up/Down
              +|/ State=Normal/Leaving/Joining/Moving
              +--  Address        Load       Tokens       Owns    Host ID                               Rack
              +UN  10.43.125.110  74.62 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
              +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
              +UN  10.43.191.172  74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
              +
              +
              +
            8. +
            9. Run the repair on the cluster to make sure that the data is synced with the other nodes in the cluster. +You can use Scylla Manager to run the repair.

            10. +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/nodeoperations/restore.html b/v1.11/nodeoperations/restore.html new file mode 100644 index 00000000000..aecd1778988 --- /dev/null +++ b/v1.11/nodeoperations/restore.html @@ -0,0 +1,777 @@ + + + + + + + + + + + + + Restore from backup | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Restore from backup

            +

            This procedure will describe how to restore from backup taken using Scylla Manager to a fresh empty cluster of any size.

            +
            +

            Caution

            +

            Due to a bug in Scylla Manager not supporting ScyllaClusters having both non-TLS and TLS CQL ports open, you have to disable the TLS certificate management +in Scylla Operator. +This step will no longer be required, when the bug is fixed.

            +

            To disable TLS certificate management in Scylla Operator add --feature-gates="AutomaticTLSCertificates=false" flag to Scylla Operator deployment.

            +
            kubectl -n scylla-operator patch deployment/scylla-operator --type=json -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--feature-gates=AutomaticTLSCertificates=false"}]'
            +
            +
            +
            +

            In the following example, the ScyllaCluster, which was used to take the backup, is called source. Backup will be restored into the ScyllaCluster named target.

            +
            + +
            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +metadata:
            +  name: source
            +  namespace: scylla
            +spec:
            +  agentVersion: 3.2.5
            +  version: 5.4.1
            +  developerMode: true
            +  backups:
            +  - name: foo
            +    location:
            +    - s3:source-backup
            +    keyspace:
            +    - '*'
            +  datacenter:
            +    name: us-east-1
            +    racks:
            +    - name: us-east-1a
            +      members: 1
            +      storage:
            +        capacity: 1Gi
            +      resources:
            +        limits:
            +          cpu: 1
            +          memory: 1Gi
            +
            +
            +
            + +
            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +metadata:
            +  name: target
            +  namespace: scylla
            +spec:
            +  agentVersion: 3.2.5
            +  version: 5.4.1
            +  developerMode: true
            +  datacenter:
            +    name: us-east-1
            +    racks:
            +    - name: us-east-1a
            +      members: 1
            +      storage:
            +        capacity: 1Gi
            +      resources:
            +        limits:
            +          cpu: 1
            +          memory: 1Gi
            +
            +
            +
            +
            +

            Make sure your target cluster is already registered in Scylla Manager. To get a list of all registered clusters, execute the following command:

            +
            $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool cluster list
            ++--------------------------------------+---------------------------------------+---------+-----------------+
            +| ID                                   | Name                                  | Port    | CQL credentials |
            ++--------------------------------------+---------------------------------------+---------+-----------------+
            +| af1dd5cd-0406-4974-949f-dc9842980080 | scylla/target                        | default | set             |
            +| ebd82268-efb7-407e-a540-3619ae053778 | scylla/source                        | default | set             |
            ++--------------------------------------+---------------------------------------+---------+-----------------+
            +
            +
            +

            Identify the tag of a snapshot which you want to restore. To get a list of all available snapshots, execute following command:

            +
            kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c <CLUSTER_ID> --all-clusters -L <BACKUP_LOCATION>
            +
            +
            +

            Where:

            +
              +
            • CLUSTER_ID - the name or ID of a registered cluster with access to BACKUP_LOCATION.

            • +
            • BACKUP_LOCATION - the location in which the backup is stored.

            • +
            +

            In this example, BACKUP_LOCATION is s3:source-backup. Use the name of cluster which has access to the backup location for CLUSTER_ID. +In this example, it’s scylla/target.

            +
            $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool backup list -c scylla/target --all-clusters -L s3:source-backup
            +backup/ff36d7e0-af2e-458c-afe6-868e0f3396b2
            +Snapshots:
            +  - sm_20240105115931UTC (409MiB, 1 nodes)
            +Keyspaces:
            +  - system_schema (15 tables)
            +  - users (9 tables)
            +
            +
            +

            In the below commands, we are restoring the sm_20240105115931UTC snapshot. Replace it with a tag of a snapshot that you want to restore. +Restoring consist of two steps. First, you’ll restore the schema, and then the data. +To restore schema, create a restore task manually on target ScyllaCluster by executing following command:

            +
            kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager --  sctool restore -c <CLUSTER_ID> -L <BACKUP_LOCATION> -T <SNAPSHOT_TAG> --restore-schema
            +
            +
            +

            Where:

            +
              +
            • CLUSTER_ID - a name or ID of a cluster you want to restore into.

            • +
            • BACKUP_LOCATION - the location in which the backup is stored.

            • +
            • SNAPSHOT_TAG - a tag of a snapshot that you want to restore.

            • +
            +

            When the task is created, the command will output the ID of a restore task.

            +
            $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-schema
            +restore/57228c52-7cf6-4271-8c8d-d446ff160747
            +
            +
            +

            Use the following command to check progress of the restore task:

            +
            $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/57228c52-7cf6-4271-8c8d-d446ff160747
            +Restore progress
            +Run:            0dd20cdf-abc4-11ee-951c-6e7993cf42ed
            +Status:         DONE - restart required (see restore docs)
            +Start time:     05 Jan 24 12:15:02 UTC
            +End time:       05 Jan 24 12:15:09 UTC
            +Duration:       6s
            +Progress:       100% | 100%
            +Snapshot Tag:   sm_20240105115931UTC
            +
            ++---------------+-------------+----------+----------+------------+--------+
            +| Keyspace      |    Progress |     Size |  Success | Downloaded | Failed |
            ++---------------+-------------+----------+----------+------------+--------+
            +| system_schema | 100% | 100% | 214.150k | 214.150k |   214.150k |      0 |
            ++---------------+-------------+----------+----------+------------+--------+
            +
            +
            +

            As suggested in the progress output, you will need to execute a rolling restart of the ScyllaCluster.

            +
            kubectl patch scyllacluster target --type merge -p '{"spec": {"forceRedeploymentReason": "schema restored"}}'
            +
            +
            +

            Use the following commands to wait until restart is finished:

            +
            $ kubectl wait --for='condition=Progressing=False' -n scylla scyllaclusters.scylla.scylladb.com/target
            +scyllacluster.scylla.scylladb.com/target condition met
            +
            +$ kubectl wait --for='condition=Degraded=False' -n scylla scyllaclusters.scylla.scylladb.com/target
            +scyllacluster.scylla.scylladb.com/target condition met
            +
            +$ kubectl wait --for='condition=Available=True' -n scylla scyllaclusters.scylla.scylladb.com/target
            +scyllacluster.scylla.scylladb.com/target condition met
            +
            +
            +

            To restore the tables content, create a restore task manually on target ScyllaCluster by executing the following command:

            +
            kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c <CLUSTER_ID> -L <BACKUP_LOCATION> -T <SNAPSHOT_TAG> --restore-tables
            +
            +
            +

            Where:

            +
              +
            • CLUSTER_ID - a name or ID of a cluster you want to restore into.

            • +
            • BACKUP_LOCATION - the location in which the backup is stored.

            • +
            • SNAPSHOT_TAG - a tag of a snapshot that you want to restore.

            • +
            +

            When the task is created, the command will output the ID of a restore task.

            +
            $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool restore -c scylla/target -L s3:source-backup -T sm_20240105115931UTC --restore-tables
            +restore/63642069-bed5-4def-ba0f-68c49e47ace1
            +
            +
            +

            Use the following command to check progress of the restore task:

            +
            $ kubectl -n scylla-manager exec -ti deployment.apps/scylla-manager -- sctool progress -c scylla/target restore/63642069-bed5-4def-ba0f-68c49e47ace1
            +Restore progress
            +Run:            ab015cef-abc8-11ee-9521-6e7993cf42ed
            +Status:         DONE
            +Start time:     05 Jan 24 12:48:04 UTC
            +End time:       05 Jan 24 12:48:15 UTC
            +Duration:       11s
            +Progress:       100% | 100%
            +Snapshot Tag:   sm_20240105115931UTC
            +
            ++-------------+-------------+--------+---------+------------+--------+
            +| Keyspace    |    Progress |   Size | Success | Downloaded | Failed |
            ++-------------+-------------+--------+---------+------------+--------+
            +| users       | 100% | 100% | 409MiB |  409MiB |     409MiB |      0 |
            ++-------------+-------------+--------+---------+------------+--------+
            +
            +Post-restore repair progress
            +Run:            ab015cef-abc8-11ee-9521-6e7993cf42ed
            +Status:         DONE
            +Start time:     05 Jan 24 12:48:04 UTC
            +End time:       05 Jan 24 12:48:15 UTC
            +Duration:       11s
            +Progress:       100%
            +Intensity:      1
            +Parallel:       0
            +Datacenters:
            +  - us-east-1
            +
            ++-------------+--------------+----------+----------+
            +| Keyspace    |        Table | Progress | Duration |
            ++-------------+--------------+----------+----------+
            +| users       | users        | 100%     | 0s       |
            ++-------------+--------------+----------+----------+
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/nodeoperations/scylla-upgrade.html b/v1.11/nodeoperations/scylla-upgrade.html new file mode 100644 index 00000000000..fa41ab2c166 --- /dev/null +++ b/v1.11/nodeoperations/scylla-upgrade.html @@ -0,0 +1,659 @@ + + + + + + + + + + + + + Upgrading version of Scylla | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Upgrading version of Scylla

            +

            To upgrade Scylla version using Operator user have to modify existing ScyllaCluster definition.

            +

            In this example cluster will be upgraded to version 4.4.5.

            +
            kubectl -n scylla patch ScyllaCluster simple-cluster  -p '{"spec":{"version": "4.4.5"}}' --type=merge
            +
            +
            +

            Operator supports two types of version upgrades:

            +
              +
            1. Patch upgrade

            2. +
            3. Generic upgrade

            4. +
            +

            Patch upgrade

            +

            Patch upgrade is executed when only patch version change is detected according to semantic versioning format. +Procedure simply rolls out a restart of whole cluster and upgrades Scylla container image for each node one by one.

            +

            Example: 4.0.0 -> 4.0.1

            +

            Generic upgrade

            +

            Generic upgrades are executed for the non patch version changes.

            +

            Example: 4.0.0 -> 2020.1.0 or 4.0.0 -> 4.1.0 or even 4.0.0 -> nightly

            +

            User can observe current state of upgrade in ScyllaCluster status.

            +
            kubectl -n scylla describe ScyllaCluster simple-cluster
            +[...]
            +Status:
            +  Racks:
            +    us-east-1a:
            +      Members:        3
            +      Ready Members:  3
            +      Version:        4.1.9
            +  Upgrade:
            +    Current Node:         simple-cluster-us-east-1-us-east-1a-2
            +    Current Rack:         us-east-1a
            +    Data Snapshot Tag:    so_data_20201228135002UTC
            +    From Version:         4.1.9
            +    State:                validate_upgrade
            +    System Snapshot Tag:  so_system_20201228135002UTC
            +    To Version:           4.2.2
            +
            +
            +

            Each upgrade begins with taking a snapshot of system and system_schema keyspaces on all nodes in parallel. +Name of this snapshot tag is saved in upgrade status under System Snapshot Tag.

            +

            Before nodes in rack are upgraded, underlying StatefulSet is changed to use OnDelete UpgradeStrategy. +This allows Operator have a full control over when Pod image is changed.

            +

            When a node is being upgraded, maintenance mode is enabled, then the node is drained and snapshot of all data keyspaces is taken. +Snapshot tag is saved under Data Snapshot Tag and is the same for all nodes during the procedure. +Once everything is set up, maintenance mode is disabled and Scylla Pod is deleted. Underlying StatefulSet will bring up a new +Pod with upgraded version. +Once Pod will become ready, data snapshot from this particular node is removed, and Operator moves to next node.

            +

            Once every rack is upgraded, system snapshot is removed from all nodes in parallel and previous StatefulSet UpgradeStrategy is restored. +At this point, all your nodes should be already in desired version.

            +

            Current state of upgrade can be traced using Current Node, Current Rack and State status fields.

            +
              +
            • Current Node shows which node is being upgraded.

            • +
            • Current Rack displays which rack is being upgraded.

            • +
            • State contain information at which stage upgrade is.

            • +
            +

            State can have following values:

            +
              +
            • begin_upgrade - upgrade is starting

            • +
            • check_schema_agreement - Operator waits until all nodes reach schema agreement. It waits for it for 1 minute, prints an error log message and check is retried.

            • +
            • create_system_backup - system keyspaces snapshot is being taken

            • +
            • find_next_rack - Operator finds out which rack must be upgraded next, decision is saved in Current Rack

            • +
            • upgrade_image_in_pod_spec - Image and UpgradeStrategy is upgraded in underlying StatefulSet

            • +
            • find_next_node - Operator finds out which node must be upgraded next, decision is saved in Current Node

            • +
            • enable_maintenance_mode - maintenance mode is being enabled

            • +
            • drain_node - node is being drained

            • +
            • backup_data - snapshot of data keyspaces is being taken

            • +
            • disable_maintenance_mode - maintenance mode is being disabled

            • +
            • delete_pod - Scylla Pod is being deleted

            • +
            • validate_upgrade - Operator validates if new pod enters Ready state and if Scylla version is upgraded

            • +
            • clear_data_backup - snapshot of data keyspaces is being removed

            • +
            • clear_system_backup - snapshot of system keyspaces is being removed

            • +
            • restore_upgrade_strategy - restore UpgradeStrategy in underlying StatefulSet

            • +
            • finish_upgrade - upgrade cleanup

            • +
            +

            Recovering from upgrade failure

            +

            Upgrade may get stuck on validate_upgrade stage. This happens when Scylla Pod refuses to properly boot up.

            +

            To continue with upgrade, first turn off operator by scaling Operator replicas to zero:

            +
            kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=0
            +
            +
            +

            Then user have to manually resolve issue with Scylla by checking what is the root cause of a failure in Scylla container logs. +If needed data and system keyspaces SSTable snapshots are available on the node. You can check ScyllaCluster status for their names.

            +

            Once issue is resolved and Scylla Pod is up and running (Pod is in Ready state), scale Operator back to two replicas:

            +
            kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=2
            +
            +
            +

            Operator should continue upgrade process from where it left off.

            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/objects.inv b/v1.11/objects.inv new file mode 100644 index 00000000000..02d81b59158 --- /dev/null +++ b/v1.11/objects.inv @@ -0,0 +1,7 @@ +# Sphinx inventory version 2 +# Project: Scylla Operator +# Version: +# The remainder of this file is compressed using zlib. +xڝVn0+j[[bma wX\__)Nы-fpll,;llWw1jO3=rN4J#؛Z&FJ3QYԂ%}HwƂF;yۂ`Jޢ'[Y+I[xD=4p9ԗ=/0%t]kASfYJjzV X$D蚛 ) Q,`  7H~+D}P;-d\Lhw$7Ds }[AA4i?wUA}k6O90?hz x>pOaR]nT{/ B_OW IՃ8@M "{}>pQB$2Q32vI,SAf2{=_3 KH +jPs|&t W[~H("䢾e]E5h%֯?7M ֹ/9IW| Y此^r3_Uj':.fhG;bG@ +VڒP)_&[i M6لeJ?폌G7KЉ ;fk['M@pBN2gs9m6ktU~ ^D) $ar[fP*ܥE$5] Qq1ns%L/Q \ No newline at end of file diff --git a/v1.11/performance.html b/v1.11/performance.html new file mode 100644 index 00000000000..3322b31accb --- /dev/null +++ b/v1.11/performance.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Performance tuning | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Performance tuning

            +

            Scylla Operator 1.6 introduces a new experimental feature allowing users to optimize Kubernetes nodes.

            +
            +

            Node tuning

            +

            Starting from Operator 1.6, a new CRD called NodeConfig is available, allowing users to target Nodes which should be tuned. +When a Node is supposed to be optimized, the Scylla Operator creates a DaemonSet covering these Nodes. +Nodes matching the provided placement conditions will be subject to tuning.

            +

            Below example NodeConfig tunes nodes having scylla.scylladb.com/node-type=scylla label:

            +
            apiVersion: scylla.scylladb.com/v1alpha1
            +kind: NodeConfig
            +metadata:
            + name: cluster
            +spec:
            + placement:
            +   nodeSelector:
            +     scylla.scylladb.com/node-type: scylla
            +
            +
            +

            For more details about new CRD use:

            +
            kubectl explain nodeconfigs.scylla.scylladb.com/v1alpha1
            +
            +
            +

            For all optimizations we use a Python script available in the Scylla image called perftune. +Perftune executes the performance optmizations like tuning the kernel, network, disk devices, spreading IRQs across CPUs and more.

            +

            Tuning consists of two separate optimizations: common node tuning, and tuning based on Scylla Pods and their resource assignment. +Node tuning is executed immediately. Pod tuning is executed when Scylla Pod lands on the same Node.

            +

            Scylla works most efficently when it’s pinned to CPU and not interrupted. +One of the most common causes of context-switching are network interrupts. Packets coming to a node need to be processed, +and this requires CPU shares.

            +

            On K8s we always have at least a couple of processes running on the node: kubelet, kubernetes provider applications, daemons etc. +These processes require CPU shares, so we cannot dedicate entire node processing power to Scylla, we need to leave space for others.
            +We take advantage of it, and we pin IRQs to CPUs not used by any Scylla Pods exclusively.

            +

            Tuning resources are created in a special namespace called scylla-operator-node-tuning.

            +

            The tuning is applied only to pods with Guaranteed QoS class. Please double check your ScyllaCluster resource specification +to see if it meets all conditions.

            +
            +
            +

            Kubernetes tuning

            +

            By default, the kubelet uses the CFS quota to enforce pod CPU limits.
            +When the node runs many CPU-bound pods, the workload can move around different CPU cores depending on whether the pod +is throttled and which CPU cores are available. +However, kubelet may be configured to assign CPUs exclusively, by setting the CPU manager policy to static.

            +

            Setting up kubelet configuration is provider specific. Please check the docs for your distribution or talk to your +provider.

            +

            Only pods within the Guaranteed QoS class) can take advantage of this option. +When such pod lands on a Node, kubelet will pin them to specific CPUs, and those won’t be part of the shared pool.

            +

            In our case there are two requirements each ScyllaCluster must fulfill to receive a Guaranteed QoS class:

            +
              +
            • resource request and limits must be equal or only limits have to be provided

            • +
            • agentResources must be provided and their requests and limits must be equal, or only limits have to be provided

            • +
            +

            An example of such a ScyllaCluster that receives a Guaranteed QoS class is below:

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +metadata:
            +  name: guaranteed-cluster
            +  namespace: scylla
            +spec:
            +  version: 4.5.1
            +  agentVersion: 2.5.2
            +  datacenter:
            +    name: us-east-1
            +    racks:
            +    - name: us-east-1a
            +      members: 3
            +      storage:
            +        capacity: 500Gi
            +      agentResources:
            +        requests:
            +          cpu: 1
            +          memory: 1G
            +        limits:
            +          cpu: 1
            +          memory: 1G
            +      resources:
            +        requests:
            +          cpu: 4
            +          memory: 16G
            +        limits:
            +          cpu: 4
            +          memory: 16G
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/releases.html b/v1.11/releases.html new file mode 100644 index 00000000000..0bca2a74300 --- /dev/null +++ b/v1.11/releases.html @@ -0,0 +1,816 @@ + + + + + + + + + + + + + Releases | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Releases

            +
            +

            Schedule

            +

            We are aiming to ship a new release approximately every 6 weeks. The following release schedule is only advisory, there are no commitments made to hitting these dates.

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

            Release

            Code freeze

            General availability

            1.11

            2023-10-02

            2023-10-16

            +
            +
            +

            Supported releases

            +

            We support the latest 2 releases of the operator to give everyone time to upgrade.

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

            Release

            General availability

            Support ends

            1.10

            2023-08-25

            Release of 1.12

            1.9

            2023-07-04

            Release of 1.11

            1.8

            2023-01-25

            2023-08-25

            1.7

            2022-01-27

            2023-07-04

            1.6

            2021-12-03

            2023-01-25

            1.5

            2021-09-16

            2022-01-27

            1.4

            2021-08-10

            2021-12-03

            1.3

            2021-06-17

            2021-09-16

            1.2

            2021-05-06

            2021-08-10

            1.1

            2021-03-22

            2021-06-17

            1.0

            2021-01-21

            2021-05-06

            +
            +

            Backport policy

            +

            Usually, only important bug fixes are eligible for being backported. +This may depend on the situation and assessment of the maintainers.

            +
            +
            +
            +

            CI/CD

            +

            We use GitHub actions for our CI/CD. Every merge to a supported branch, or a creation of a tag will automatically trigger a job to build, test and publish the container image and other artifacts like helm charts. Before we publish any image, it must pass the e2e suite.

            +
            +

            Automated promotions

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

            Git reference

            Type

            Container image

            master

            branch

            docker.io/scylladb/scylla-operator:latest

            vX.Y

            branch

            docker.io/scylladb/scylla-operator:X.Y

            vX.Y.Z

            tag

            docker.io/scylladb/scylla-operator:X.Y.Z

            vX.Y.Z-alpha.N

            tag

            docker.io/scylladb/scylla-operator:X.Y.Z-alpha.N

            vX.Y.Z-beta.N

            tag

            docker.io/scylladb/scylla-operator:X.Y.Z-beta.N

            vX.Y.Z-rc.N

            tag

            docker.io/scylladb/scylla-operator:X.Y.Z-rc.N

            +
            +
            +

            Generally available

            +

            GA images aren’t build from scratch but rather promoted from an existing release candidates. When we decide a release candidate has the acceptable quality and QA sings it off, the release candidate is promoted to become the GA release. This makes sure the image has exactly the same content and SHA as the tested release candidate.

            +
            +
            +
            +

            Support matrix

            +

            Support matrix table shows the version requirements for a particular scylla-operator version. Be sure to match these requirements, otherwise some functionality will not work.

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

            v1.10

            v1.9

            v1.8

            v1.7

            v1.6

            v1.5

            v1.4

            v1.3

            v1.2

            v1.1

            v1.0

            Kubernetes

            >=1.21

            >=1.21

            >=1.21

            >=1.20 && <1.25

            >=1.19.10 && <1.25

            >=1.19.10

            >=1.19.10

            >=1.19

            >=1.19

            >=1.11

            >=1.11

            CRI API

            v1

            v1

            v1alpha2

            v1alpha2

            v1alpha2

            Scylla OS

            >=5.0

            >=5.0

            >=5.0

            >=4.3

            >=4.3

            >=4.3

            >=4.3

            >=4.2

            >=4.2

            >=4.0

            >=4.0

            Scylla Enterprise

            >=2021.1

            >=2021.1

            >=2021.1

            >=2021.1

            >=2021.1

            >=2021.1

            >=2021.1

            >=2020.1

            >=2020.1

            >=2020.1

            >=2020.1

            Scylla Manager

            >=2.6

            >=2.6

            >=2.6

            >=2.2

            >=2.2

            >=2.2

            >=2.2

            >=2.2

            >=2.2

            >=2.2

            >=2.2

            Scylla Monitoring

            >=4.0

            >=4.0

            >=4.0

            >=3.0

            >=3.0

            >=1.0

            >=1.0

            >=1.0

            >=1.0

            >=1.0

            >=1.0

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/scylla-cluster-crd.html b/v1.11/scylla-cluster-crd.html new file mode 100644 index 00000000000..0955099b05c --- /dev/null +++ b/v1.11/scylla-cluster-crd.html @@ -0,0 +1,800 @@ + + + + + + + + + + + + + Scylla Cluster CRD | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Scylla Cluster CRD

            +

            Scylla database clusters can be created and configured using the clusters.scylla.scylladb.com custom resource definition (CRD).

            +

            Please refer to the the user guide walk-through for deployment instructions. +This page will explain all the available configuration options on the Scylla CRD.

            +
            +

            Sample

            +
            apiVersion: scylla.scylladb.com/v1
            +kind: ScyllaCluster
            +metadata:
            +  name: simple-cluster
            +  namespace: scylla
            +spec:
            +  version: 2.3.1
            +  repository: scylladb/scylla
            +  developerMode: true
            +  cpuset: false
            +  automaticOrphanedNodeCleanup: true
            +  repairs:
            +  - name: "weekly us-east-1 repair"
            +    intensity: "2"
            +    interval: "7d"
            +    dc: ["us-east-1"]
            +  backups:
            +  - name: "daily users backup"
            +    rateLimit: ["50"]
            +    location: ["s3:cluster-backups"]
            +    interval: "1d"
            +    keyspace: ["users"]
            +  - name: "weekly full cluster backup"
            +    rateLimit: ["50"]
            +    location: ["s3:cluster-backups"]
            +    interval: "7d"
            +  datacenter:
            +    name: us-east-1
            +    racks:
            +      - name: us-east-1a
            +        members: 3
            +        storage:
            +          capacity: 500G
            +          storageClassName: local-raid-disks
            +        resources:
            +          requests:
            +            cpu: 8
            +            memory: 32Gi
            +          limits:
            +            cpu: 8
            +            memory: 32Gi
            +        placement:
            +          nodeAffinity:
            +            requiredDuringSchedulingIgnoredDuringExecution:
            +              nodeSelectorTerms:
            +                - matchExpressions:
            +                  - key: failure-domain.beta.kubernetes.io/region
            +                    operator: In
            +                    values:
            +                      - us-east-1
            +                  - key: failure-domain.beta.kubernetes.io/zone
            +                    operator: In
            +                    values:
            +                      - us-east-1a
            +          tolerations:
            +            - key: role
            +              operator: Equal
            +              value: scylla-clusters
            +              effect: NoSchedule
            +
            +
            +
            +
            +

            Settings Explanation

            +
            +

            Cluster Settings

            +
              +
            • version: The version of Scylla to use. It is used as the image tag to pull.

            • +
            • agentVersion: The version of Scylla Manager Agent to use. It is used as the image tag to pull.

            • +
            • repository: Optional field. Specifies a custom image repo. If left unset, the official docker hub repo is used (scylladb/scylla).

            • +
            • agentRepository: Optional field. Specifies a custom Scylla Manager Agent image repo. If left unset, the official docker hub repo is used (scylladb/scylla).

            • +
            • developerMode: Optional field. If it’s true, then Scylla is started in developer mode. This setting is for shared test/dev environments.

            • +
            • cpuset: Optional field. If it’s true, then the operator will start Scylla with cpu pinning for maximum performance. For this to work, you need to set the kubelet to use the static cpu policy and only specify limits in resources.

            • +
            • automaticOrphanedNodeCleanup: Optional field. Controls if automatic orphan node cleanup should be performed.

            • +
            • alternator: Optional field. Defines Alternator configuration.

              +
                +
              • port: Port on which to bind to Alternator API.

              • +
              • writeIsolation: required Desired write isolation.

              • +
              +
            • +
            • genericUpgrade: Optional field. Defines GenericUpgrade configuration.

              +
                +
              • failureStrategy: specifies which logic is executed when upgrade failure happens. Currently only Retry is supported.

              • +
              • pollInterval: specifies how often upgrade logic polls on state updates. +Increasing this value should lower number of requests sent to the kube-apiserver, but it may affect +overall time spent during upgrade.

              • +
              +
            • +
            • datacenter: Datacenter definition.

            • +
            • sysctls: Optional field. Sysctl properties to be applied during initialization.

            • +
            • scyllaArgs: Optional field. Command line argument passed to Scylla container image. Note: not all Scylla versions support it.

            • +
            • network: Optional field. Allows to customize network parameters.

              +
                +
              • hostNetworking: controls if host networking should be enabled.

              • +
              • dnsPolicy: controls Scylla Pod DNS Policy. See details.

              • +
              +
            • +
            • repairs: Optional field. Repair tasks definitions. See Scylla Manager settings for details.

            • +
            • backups: Optional field. Repair tasks definitions. See Scylla Manager settings for details.

            • +
            +

            In the Scylla model, each cluster contains datacenters and each datacenter contains racks. At the moment, the operator only supports single datacenter setups.

            +
            +
            +

            Scylla Manager settings

            +

            Tasks are scheduled only when Scylla Manager is deployed in K8s cluster.

            +

            Repairs:

            +
              +
            • name - required - human readable name of the task. It must be unique across all tasks.

            • +
            • startDate - specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, +valid units are d, h, m, s (default “now”).

            • +
            • interval - Optional field. Task schedule interval e.g. 3d2h10m, valid units are d, h, m, s (default “0”).

            • +
            • numRetries - Optional field. The number of times a scheduled task will retry to run before failing (default 3).

            • +
            • dc - Optional field. A list of datacenter glob patterns, e.g. ["dc1", "!otherdc*"] used to specify the DCs to include or exclude from backup.

            • +
            • failFast - Optional field. Stop repair on first error.

            • +
            • intensity - Optional field. Specifies how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. +If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). +Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. +Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. +For Scylla clusters that do not support row-level repair, intensity can be a decimal between (0,1). +In that case it specifies percent of shards that can be repaired in parallel on a repair master node. +For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1. +Intensity is a number passed as string due to lack of support for float values in k8s controller runtime

            • +
            • parallel - Optional field. Specifies the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). +Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. +The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. +The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2.

            • +
            • keyspace - Optional field. A list of keyspace/tables glob patterns, e.g. ["keyspace", "!keyspace.table_prefix_*"] +used to include or exclude keyspaces from repair.

            • +
            • smallTableThreshold - Optional field. Enable small table optimization for tables of size lower than given threshold. +Supported units [B, MiB, GiB, TiB] (default "1GiB").

            • +
            +

            Backups:

            +
              +
            • name - required - human readable name of the task. It must be unique across all tasks.

            • +
            • startDate - Optional field. Specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, +valid units are d, h, m, s (default “now”).

            • +
            • interval - Optional field. task schedule interval e.g. 3d2h10m, valid units are d, h, m, s (default “0”).

            • +
            • numRetries - Optional field. the number of times a scheduled task will retry to run before failing (default 3).

            • +
            • dc - Optional field. A list of datacenter glob patterns, e.g. ["dc1","!otherdc*"] used to specify the DCs to include or exclude from backup.

            • +
            • keyspace - Optional field. A list of keyspace/tables glob patterns, e.g. ["keyspace","!keyspace.table_prefix_*"] used to include or exclude keyspaces from backup.

            • +
            • location - Optional field. A list of backup locations in the format [<dc>:]<provider>:<name> ex. s3:my-bucket. +The <dc>: part is optional and is only needed when different datacenters are being used to upload data to different locations. +<name> Optional field. must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. +The only supported storage at the moment are s3 and gcs.

            • +
            • rateLimit - Optional field. A list of megabytes (MiB) per second rate limits expressed in the format [<dc>:]<limit>. +The <dc>: part is optional and only needed when different datacenters need different upload limits. +Set to 0 for no limit (default 100).

            • +
            • retention - Optional field. The number of backups which are to be stored (default 3).

            • +
            • snapshotParallel - Optional field. A list of snapshot parallelism limits in the format [<dc>:]<limit>. +The <dc>: part is optional and allows for specifying different limits in selected datacenters. +If The <dc>: part is not set, the limit is global (e.g. ["dc1:2,5"]) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters.

            • +
            • uploadParallel - Optional field. A list of upload parallelism limits in the format [<dc>:]<limit>. +The <dc>: part is optional and allows for specifying different limits in selected datacenters. +If The <dc>: part is not set the limit is global (e.g. ["dc1:2,5"]) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters.

            • +
            +
            +
            +

            Datacenter Settings

            +
              +
            • name: Name of the datacenter. Usually, a datacenter corresponds to a region.

            • +
            • racks: List of racks for the specific datacenter.

            • +
            +
            +
            +

            Rack Settings

            +
              +
            • name: Name of the rack. Usually, a rack corresponds to an availability zone.

            • +
            • members: Number of Scylla members for the specific rack. (In Scylla documentation, they are called nodes. We don’t call them nodes to avoid confusion as a Scylla Node corresponds to a Kubernetes Pod, not a Kubernetes Node).

            • +
            • storage: Defines the specs of the underlying storage.

              +
                +
              • capacity: Capacity of the PersistentVolume to request.

              • +
              • storageClassName: Optional field. StorageClass of PersistentVolume to request.

              • +
              +
            • +
            • resources: Defines the CPU and RAM resources for the Scylla Pods.

              +
                +
              • requests: The minimum amount of resources needed to run a Scylla container.

                +
                  +
                • cpu: CPU requests.

                • +
                • memory: RAM requests.

                • +
                +
              • +
              • limits: The maximum amount of resources that can be used by a Scylla container.

                +
                  +
                • cpu: CPU limits.

                • +
                • memory: RAM limits.

                • +
                +
              • +
              +
            • +
            • agentResources: Optional field. Defines the CPU and RAM resources for the Scylla Manager Agent container. See resources for details.

            • +
            • volumes: Optional field. Defines volumes available in Scylla Pod. See details.

            • +
            • volumeMounts: Optional field. Defines which volumes will be attached to Scylla container.

            • +
            • agentVolumeMounts: Optional field. Defines which volumes will be attached to Agent container.

            • +
            • scyllaConfig: Optional field. name of custom config map which will be merged with Scylla config.

            • +
            • scyllaAgentConfig: Optional field. name of custom secret which will be merged with Scylla Manager Agent config.

            • +
            • placement: Optional field. Defines the placement of Scylla Pods. Has the following subfields:

              + +
            • +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/search.html b/v1.11/search.html new file mode 100644 index 00000000000..83a99fb8510 --- /dev/null +++ b/v1.11/search.html @@ -0,0 +1,552 @@ + + + + + + + + + + + + + Search | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + + + +
            + + + + + +
            + + +
            + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/searchindex.js b/v1.11/searchindex.js new file mode 100644 index 00000000000..41a1b5ee407 --- /dev/null +++ b/v1.11/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["contributing", "eks", "exposing", "generic", "gke", "helm", "index", "manager", "migration", "monitoring", "multidc/eks", "multidc/gke", "multidc/index", "multidc/multidc", "nodeoperations/automatic-cleanup", "nodeoperations/index", "nodeoperations/maintenance-mode", "nodeoperations/replace-node", "nodeoperations/restore", "nodeoperations/scylla-upgrade", "performance", "releases", "scylla-cluster-crd", "support/index", "support/known-issues", "support/must-gather", "support/overview", "support/troubleshooting/index", "support/troubleshooting/installation", "upgrade"], "filenames": ["contributing.md", "eks.md", "exposing.md", "generic.md", "gke.md", "helm.md", "index.rst", "manager.md", "migration.md", "monitoring.md", "multidc/eks.md", "multidc/gke.md", "multidc/index.rst", "multidc/multidc.md", "nodeoperations/automatic-cleanup.md", "nodeoperations/index.rst", "nodeoperations/maintenance-mode.md", "nodeoperations/replace-node.md", "nodeoperations/restore.md", "nodeoperations/scylla-upgrade.md", "performance.md", "releases.md", "scylla-cluster-crd.md", "support/index.rst", "support/known-issues.md", "support/must-gather.md", "support/overview.md", "support/troubleshooting/index.rst", "support/troubleshooting/installation.md", "upgrade.md"], "titles": ["Contributing to Scylla Operator", "Deploying Scylla on EKS", "Exposing ScyllaCluster", "Deploying Scylla on a Kubernetes Cluster", "Deploying Scylla on GKE", "Deploying Scylla stack using Helm Charts", "Scylla Operator Documentation", "Deploying Scylla Manager on a Kubernetes Cluster", "Version migrations", "Monitoring", "Build multiple Amazon EKS clusters with inter-Kubernetes networking", "Build multiple GKE clusters with inter-Kubernetes networking", "Deploying multi-datacenter ScyllaDB clusters in Kubernetes", "Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters", "Automatic cleanup and replacement in case when k8s node is lost", "Node operations using Scylla Operator", "Maintenance mode", "Replacing a Scylla node", "Restore from backup", "Upgrading version of Scylla", "Performance tuning", "Releases", "Scylla Cluster CRD", "Support", "Known issues", "Gathering data with must-gather", "Support overview", "Troubleshooting", "Troubleshooting installation issues", "Upgrade of Scylla Operator"], "terms": {"To": [0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 16, 17, 18, 19, 24, 26, 28, 29], "environ": [0, 2, 3, 5, 8, 13, 22, 25], "must": [0, 2, 3, 7, 13, 17, 19, 20, 21, 22, 23, 26, 29], "have": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 18, 19, 20, 25, 28, 29], "follow": [0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 18, 19, 21, 22, 24, 29], "go": [0, 3, 5, 8, 13, 17, 29], "1": [0, 1, 2, 3, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 20, 21, 22], "13": [0, 7], "make": [0, 3, 4, 5, 7, 8, 9, 13, 17, 18, 21, 25, 28, 29], "sure": [0, 3, 4, 5, 7, 8, 13, 17, 18, 21, 25, 28, 29], "gopath": 0, "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 28, 29], "set": [0, 2, 5, 6, 7, 9, 13, 18, 19, 20, 24, 25], "home": 0, "kustom": 0, "v3": 0, "0": [0, 2, 3, 4, 5, 7, 9, 10, 11, 13, 17, 18, 19, 21, 22, 25], "kubebuild": 0, "v2": 0, "3": [0, 1, 3, 5, 7, 13, 18, 19, 20, 21, 22], "docker": [0, 3, 5, 21, 22, 29], "git": [0, 3, 8, 21, 29], "client": [0, 3, 5, 8, 9, 13, 17], "instal": [0, 3, 6, 7, 8, 9, 10, 11, 13, 25, 27, 29], "github": [0, 3, 6, 9, 21, 25], "account": [0, 4], "all": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 18, 19, 20, 22, 25], "depend": [0, 2, 8, 16, 17, 20, 21, 22, 25], "dep": 0, "simpli": [0, 3, 5, 8, 16, 19], "run": [0, 1, 4, 5, 6, 7, 8, 9, 13, 17, 18, 19, 20, 22, 29], "sh": [0, 1, 4], "from": [0, 1, 2, 3, 4, 5, 8, 9, 10, 13, 15, 16, 17, 19, 20, 21, 22, 25, 29], "browser": 0, "navig": 0, "http": [0, 1, 3, 5, 7, 9, 25, 29], "com": [0, 1, 2, 3, 4, 5, 8, 9, 13, 18, 20, 22, 25, 29], "scylladb": [0, 2, 3, 5, 6, 8, 9, 18, 20, 21, 22, 25, 26, 29], "click": 0, "button": 0, "open": [0, 2, 3, 6, 7, 18], "consol": 0, "window": 0, "do": [0, 3, 7, 9, 10, 11, 16, 22, 26, 28, 29], "repo": [0, 5, 8, 22, 29], "path": [0, 3, 8, 13, 18, 25, 29], "mkdir": 0, "p": [0, 3, 4, 8, 13, 18, 19, 29], "src": 0, "local": [0, 9, 10, 13, 17, 22], "cd": [0, 1, 3, 4], "where": [0, 1, 4, 8, 18, 19, 28], "user": [0, 3, 4, 6, 7, 8, 9, 16, 18, 19, 20, 22, 25, 28, 29], "name": [0, 1, 3, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 20, 22, 25, 29], "first": [0, 1, 3, 4, 5, 7, 8, 9, 18, 19, 22, 29], "you": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 22, 25, 28, 29], "need": [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 13, 17, 18, 19, 20, 22, 25, 28, 29], "list": [0, 3, 4, 7, 8, 11, 18, 22, 29], "verifi": [0, 3, 13, 17], "wa": [0, 3, 5, 7, 8, 10, 17, 18, 29], "ad": [0, 3, 6, 10], "v": [0, 25], "now": [0, 1, 3, 4, 7, 8, 10, 11, 13, 22], "should": [0, 2, 3, 5, 7, 8, 9, 10, 11, 13, 17, 19, 20, 22], "least": [0, 4, 5, 13, 20, 25], "origin": [0, 13], "can": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 19, 20, 22, 25, 26, 28], "also": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 25], "other": [0, 2, 4, 5, 6, 7, 9, 10, 11, 13, 17, 20, 21, 22, 25], "collabor": 0, "contributor": 0, "featur": [0, 18, 20], "bug": [0, 18, 21, 26], "fix": [0, 18, 21, 24], "pr": 0, "us": [0, 1, 2, 3, 4, 6, 7, 8, 10, 11, 17, 18, 19, 20, 21, 22, 25, 28, 29], "makefil": 0, "command": [0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 22, 24, 25], "chang": [0, 3, 4, 5, 7, 8, 9, 13, 19, 22, 29], "img": 0, "variabl": [0, 13, 25], "repositori": [0, 3, 22, 29], "access": [0, 2, 7, 18], "push": 0, "wait": [0, 3, 5, 8, 13, 18, 19, 29], "imag": [0, 4, 8, 11, 19, 20, 21, 22, 29], "built": [0, 2, 10, 11], "upload": [0, 22], "new": [0, 3, 4, 6, 7, 8, 9, 10, 13, 17, 19, 20, 21, 29], "base": [0, 5, 20], "start": [0, 1, 3, 7, 10, 18, 19, 20, 22], "work": [0, 1, 4, 5, 8, 10, 11, 13, 20, 21, 22], "ensur": [0, 3, 8], "ar": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 20, 21, 22, 25, 26, 28, 29], "up": [0, 2, 5, 6, 8, 9, 13, 17, 19, 20, 29], "date": [0, 5, 7, 13, 21, 22, 29], "latest": [0, 1, 6, 21, 25], "fetch": 0, "off": [0, 3, 16, 19, 21, 29], "master": [0, 21, 22], "give": [0, 3, 4, 7, 21], "simpl": [0, 2, 3, 5, 7, 8, 16, 17, 19, 22, 29], "descript": [0, 5], "gener": [0, 1, 2, 3, 4, 7, 8, 9, 19, 29], "two": [0, 2, 5, 7, 8, 10, 11, 13, 18, 19, 20, 29], "three": [0, 5, 7], "word": [0, 13], "separ": [0, 1, 2, 4, 8, 10, 20], "dash": [0, 22], "without": [0, 2, 4, 5, 9, 25], "number": [0, 3, 22, 29], "checkout": [0, 8, 29], "b": [0, 4, 11, 13, 16, 22], "readi": [0, 3, 5, 7, 8, 10, 11, 16, 17, 19, 29], "dure": [0, 13, 19, 22, 29], "lifecycl": [0, 13], "keep": [0, 1, 4], "As": [0, 1, 4, 7, 10, 13, 18, 25], "team": 0, "rebas": 0, "top": 0, "thi": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 16, 17, 18, 19, 20, 21, 22, 24, 25, 28, 29], "avoid": [0, 22, 25, 28], "unnecessari": 0, "merg": [0, 2, 13, 18, 19, 21, 22], "clean": 0, "whenev": 0, "never": [0, 29], "want": [0, 1, 2, 3, 4, 5, 7, 10, 11, 18, 29], "alwai": [0, 3, 16, 20, 25], "otherwis": [0, 9, 10, 21], "end": [0, 8, 9, 18, 21], "If": [0, 1, 3, 4, 5, 7, 8, 9, 13, 19, 22, 24, 25, 28], "ani": [0, 2, 4, 5, 8, 10, 11, 18, 20, 21, 22], "modifi": [0, 3, 4, 11, 19, 28], "file": [0, 3, 4, 5, 8, 10, 25, 28, 29], "stash": 0, "them": [0, 1, 2, 3, 4, 5, 8, 9, 10, 13, 20, 22, 25, 29], "save": [0, 3, 8, 10, 13, 19, 25, 29], "u": [0, 1, 3, 4, 5, 7, 8, 10, 11, 13, 16, 17, 18, 19, 20, 22, 26], "some": [0, 2, 3, 5, 7, 17, 21, 25, 28], "veri": [0, 5, 8, 25, 29], "power": [0, 20], "understand": [0, 8, 26], "how": [0, 1, 2, 4, 5, 7, 9, 17, 18, 22, 25, 28], "els": [0, 9], "risk": 0, "lose": [0, 14], "read": [0, 1, 3, 4, 5, 8], "about": [0, 1, 2, 3, 4, 5, 11, 20], "document": [0, 1, 2, 3, 4, 5, 7, 10, 11, 13, 22], "well": [0, 1, 3, 4, 7, 8, 9], "worth": 0, "In": [0, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20, 22, 25, 29], "nutshel": 0, "doe": [0, 3, 5, 7, 13], "unwind": 0, "remov": [0, 3, 5, 8, 13, 14, 16, 19, 25, 29], "temporarili": 0, "The": [0, 1, 2, 3, 4, 6, 7, 9, 10, 11, 13, 20, 21, 22, 24, 25], "re": [0, 8, 29], "appli": [0, 1, 3, 4, 5, 7, 8, 9, 13, 20, 22, 24, 25, 29], "one": [0, 2, 3, 5, 7, 8, 11, 13, 14, 17, 19, 22, 25, 29], "conflict": 0, "prompt": 0, "befor": [0, 8, 9, 19, 21, 22, 25, 28, 29], "continu": [0, 19], "output": [0, 3, 7, 8, 11, 13, 18], "close": [0, 5], "It": [0, 1, 2, 3, 4, 5, 10, 11, 13, 19, 22], "tell": 0, "complet": [0, 3, 9, 17], "when": [0, 1, 2, 3, 4, 7, 8, 9, 11, 13, 15, 16, 18, 19, 20, 21, 22, 25, 26, 28], "done": [0, 1, 3, 4, 7, 18, 25], "see": [0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 18, 20, 22], "onc": [0, 1, 3, 4, 5, 7, 10, 11, 19, 29], "implement": [0, 13], "unit": [0, 22], "test": [0, 7, 9, 21, 22, 28], "pass": [0, 2, 4, 21, 22, 28], "integr": [0, 6, 13], "order": [0, 2, 3, 4, 7, 13, 29], "requir": [0, 1, 2, 3, 4, 10, 11, 13, 18, 20, 21, 22, 24, 26, 28, 29], "again": [0, 8, 9, 16], "prepar": [0, 12, 13], "minim": [0, 5], "logic": [0, 2, 22], "so": [0, 2, 3, 4, 5, 9, 10, 11, 13, 20, 29], "we": [0, 1, 2, 3, 4, 5, 7, 8, 9, 17, 18, 20, 21, 22, 25, 28, 29], "maintain": [0, 21], "most": [0, 1, 3, 4, 5, 9, 13, 20, 22], "commonli": 0, "includ": [0, 5, 11, 22, 26, 28], "singl": [0, 3, 5, 7, 13, 22], "squash": 0, "although": [0, 5, 8, 9, 10, 11, 13], "sometim": [0, 3, 25], "multipl": [0, 2, 3, 7, 8, 12], "inspect": 0, "determin": [0, 25], "log": [0, 3, 7, 19, 22], "edit": [0, 1, 3, 4, 7], "even": [0, 19], "reorder": 0, "exampl": [0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 16, 18, 19, 20, 25, 29], "last": 0, "5": [0, 2, 7, 13, 18, 19, 20, 21, 22], "tool": [0, 1, 9, 10, 11, 13, 25, 26], "head": 0, "pleas": [0, 5, 20, 22, 25, 28, 29], "line": [0, 10, 11, 13, 22], "summari": 0, "would": [0, 3, 7, 11, 17], "like": [0, 3, 6, 7, 8, 9, 17, 20, 21, 25], "prefix": 0, "relev": 0, "directori": [0, 25, 29], "colon": 0, "changelog": 0, "get": [0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 19, 25, 29], "made": [0, 2, 21], "look": [0, 3, 5, 8, 13, 25], "just": [0, 1, 3, 4], "good": [0, 2, 5], "more": [0, 1, 2, 3, 4, 5, 9, 10, 11, 13, 17, 20, 22, 25, 26, 28], "sai": 0, "enter": [0, 5, 17, 19], "blank": 0, "carri": [0, 13], "rememb": [0, 3], "why": 0, "itself": [0, 5, 7, 16], "show": [0, 3, 19, 21], "what": [0, 2, 3, 5, 7, 8, 9, 19, 25, 26], "write": [0, 3, 22], "better": [0, 4], "than": [0, 2, 3, 8, 17, 22, 25], "less": [0, 8, 9, 29], "compar": [0, 8], "behaviour": 0, "after": [0, 1, 3, 4, 5, 7, 17], "imagin": 0, "yourself": 0, "12": [0, 7, 18, 21], "month": 0, "time": [0, 5, 7, 8, 17, 18, 21, 22], "ve": 0, "forgotten": 0, "everyth": [0, 1, 3, 4, 5, 19], "did": 0, "speed": 0, "quickli": 0, "an": [0, 2, 3, 5, 6, 10, 11, 19, 20, 21, 22, 25, 26, 28, 29], "issu": [0, 6, 7, 8, 19, 23, 25, 27, 29], "1234": 0, "subject": [0, 20], "fit": [0, 2], "don": [0, 1, 2, 4, 5, 22, 25], "t": [0, 1, 2, 3, 4, 5, 7, 8, 17, 18, 20, 21, 22, 25, 28, 29], "associ": [0, 3, 7, 8, 10, 11], "put": 0, "link": [0, 24], "here": [0, 3, 25, 29], "short": [0, 8], "sidecar": [0, 3, 5, 8, 29], "reconcil": [0, 9], "loop": 0, "And": [0, 5], "longer": [0, 3, 4, 13, 17, 18], "api": [0, 3, 7, 9, 13, 21, 22, 25, 28], "support": [0, 2, 3, 5, 6, 7, 13, 18, 19, 22, 25, 28, 29], "host": [0, 7, 9, 13, 17, 22], "network": [0, 2, 6, 12, 17, 20, 22, 28], "crd": [0, 3, 5, 6, 7, 8, 20, 29], "ha": [0, 2, 3, 4, 10, 13, 18, 21, 22], "properti": [0, 2, 3, 22], "select": [0, 2, 3, 13, 22], "apropri": 0, "dn": [0, 2, 3, 9, 13, 16, 17, 22], "polici": [0, 1, 2, 4, 5, 20, 22], "recent": 0, "obviou": 0, "tab": 0, "track": [0, 3, 7], "automat": [0, 3, 4, 7, 11, 15, 21, 22, 29], "guid": [1, 3, 4, 5, 7, 8, 10, 11, 13, 22, 29], "focus": [1, 4], "improv": 1, "perform": [1, 3, 4, 6, 14, 22], "trick": 1, "won": [1, 2, 20, 25], "differ": [1, 2, 3, 5, 7, 10, 11, 13, 20, 22], "machin": [1, 3, 4, 9, 11, 25], "tier": 1, "kubelet": [1, 4, 20, 22], "static": [1, 4, 8, 20, 22], "cpu": [1, 3, 4, 5, 13, 18, 20, 22], "sdd": [1, 4], "disk": [1, 3, 4, 11, 17, 20, 22], "raid0": [1, 4], "maximum": [1, 4, 22], "same": [1, 2, 3, 4, 5, 7, 8, 13, 19, 20, 21, 22], "tri": [1, 4], "step": [1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 18, 25, 29], "accord": [1, 3, 4, 8, 10, 19], "your": [1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20, 24, 25, 28, 29], "prefer": [1, 4, 10, 11], "eks_region": 1, "east": [1, 3, 5, 7, 8, 10, 13, 17, 18, 19, 20, 22], "eks_zon": 1, "1a": [1, 3, 7, 8, 10, 13, 17, 18, 19, 20, 22], "1b": [1, 5, 10, 13], "1c": [1, 10, 13], "insid": [1, 3, 4, 16], "folder": [1, 4, 25], "z": [1, 4, 21, 25], "r": 1, "benchmark": [1, 4], "cassandra": [1, 4], "stress": [1, 4], "export": [1, 4, 25], "option": [1, 3, 4, 5, 7, 13, 20, 22, 25], "own": [1, 4, 5, 13, 17], "cluster_nam": [1, 3, 4], "demo": [1, 4, 17], "For": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 16, 20, 22], "ll": [1, 4, 18, 25], "A": [1, 2, 3, 4, 5, 9, 10, 11, 13, 22, 29], "nodegroup": [1, 10], "i3": 1, "2xlarg": 1, "pod": [1, 2, 3, 4, 5, 7, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22, 25, 28], "These": [1, 2, 4, 20, 29], "onli": [1, 3, 8, 10, 11, 13, 19, 20, 21, 22, 25, 29], "accept": [1, 21], "toler": [1, 13, 22], "pool": [1, 4, 11, 13, 17, 20], "instancetyp": 1, "desiredcapac": 1, "label": [1, 3, 4, 9, 13, 16, 17, 20], "type": [1, 4, 5, 8, 9, 10, 11, 13, 17, 18, 19, 20, 21], "taint": [1, 4], "role": [1, 3, 4, 8, 13, 22], "noschedul": [1, 4, 13, 22], "ssh": [1, 7, 24], "allow": [1, 3, 5, 9, 10, 11, 13, 16, 19, 20, 22, 28], "true": [1, 3, 5, 7, 9, 13, 18, 22, 29], "kubeletextraconfig": 1, "cpumanagerpolici": [1, 4], "4": [1, 3, 4, 5, 7, 18, 19, 20, 21], "c4": 1, "later": [1, 4], "larg": [1, 25], "monitor": [1, 4, 6, 13, 21], "stack": [1, 4, 6, 9], "sever": [1, 2, 10, 11, 28], "eksctl": [1, 10], "doc": [1, 3, 18, 20, 28], "aw": [1, 2, 10], "amazon": [1, 12, 13], "userguid": 1, "html": 1, "kubectl": [1, 3, 4, 5, 7, 8, 9, 10, 11, 13, 16, 17, 18, 19, 20, 25], "kubernet": [1, 2, 5, 6, 8, 9, 21, 22, 25, 28], "io": [1, 2, 3, 9, 10, 13, 21, 22, 25, 29], "task": [1, 3, 6, 13, 18, 22], "refer": [1, 3, 4, 5, 8, 9, 10, 11, 13, 21, 22, 29], "its": [1, 3, 4, 7, 8, 10, 11, 13], "except": [1, 4], "develop": [1, 4, 7, 9, 22], "mode": [1, 4, 7, 11, 15, 19, 22, 25], "storag": [1, 3, 4, 5, 9, 13, 18, 20, 22, 29], "xf": [1, 4, 13], "filesystem": [1, 4, 16], "nvme": [1, 4], "cloud": [1, 2, 3, 4, 7, 9, 11, 13], "provid": [1, 2, 3, 4, 5, 9, 10, 13, 20, 22, 26, 28], "usual": [1, 2, 4, 9, 21, 22], "come": [1, 3, 4, 7, 20], "individu": [1, 4], "devic": [1, 4, 20], "full": [1, 3, 4, 7, 8, 17, 19, 22], "capac": [1, 4, 5, 13, 18, 20, 22], "togeth": [1, 4], "form": [1, 4, 25], "raid": [1, 4, 22], "arrai": [1, 4], "those": [1, 3, 4, 20], "nodeconfig": [1, 4, 20], "necessari": [1, 3, 4, 9, 10, 11, 13, 25], "creation": [1, 4, 7, 21], "optim": [1, 4, 20, 22], "tune": [1, 4, 6], "section": [1, 2, 3, 4, 10, 11, 25, 26], "": [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 17, 18, 20, 22, 25, 28, 29], "let": [1, 4, 5, 7, 13, 25], "take": [1, 3, 4, 17, 18, 19, 20, 22, 25], "care": [1, 2, 4], "abov": [1, 3, 4, 5, 7, 9, 10, 11, 29], "server": [1, 3, 4, 7, 9, 13, 29], "side": [1, 4, 9, 13, 29], "f": [1, 3, 4, 5, 7, 8, 9, 10, 13, 29], "alpha": [1, 4, 21], "yaml": [1, 3, 4, 5, 7, 8, 9, 10, 13, 25, 29], "afterward": [1, 4], "capabl": [1, 2, 3, 4, 13], "dynam": [1, 4], "provis": [1, 2, 3, 4, 5, 13], "persistentvolum": [1, 3, 4, 22], "mount": [1, 3, 4, 25], "earlier": [1, 4, 10, 13], "over": [1, 4, 13, 17, 19], "n": [1, 3, 4, 5, 7, 8, 9, 13, 16, 17, 18, 19, 21, 22, 25, 29], "csi": [1, 4], "driver": [1, 2, 3, 4], "common": [1, 3, 4, 5, 7, 8, 20, 25, 28, 29], "storageclass_xf": [1, 4], "describ": [1, 3, 4, 7, 8, 10, 11, 13, 18, 19, 29], "launch": [1, 4], "highli": [1, 3, 4], "instruct": [1, 3, 4, 5, 8, 10, 22], "found": [1, 3, 4], "experi": [1, 4], "explain": [2, 9, 10, 11, 20, 22], "oper": [2, 7, 8, 13, 14, 16, 17, 18, 19, 20, 21, 22, 25, 26, 28], "setup": [2, 3, 9, 10, 11, 13, 22, 28], "variou": [2, 3], "configur": [2, 7, 13, 20, 22, 28, 29], "independ": [2, 13, 28], "version": [2, 3, 4, 5, 6, 7, 9, 13, 15, 18, 20, 21, 22, 29], "2023": [2, 21], "enterpris": [2, 6, 7, 21], "2": [2, 3, 4, 5, 7, 8, 10, 11, 13, 16, 17, 18, 19, 20, 21, 22], "sourc": [2, 5, 6, 7, 10, 11, 18, 29], "exposeopt": [2, 9, 13], "specifi": [2, 3, 5, 10, 13, 22], "creat": [2, 5, 7, 8, 9, 13, 18, 20, 22, 25, 29], "equival": 2, "apivers": [2, 8, 9, 10, 13, 18, 20, 22, 29], "scylla": [2, 8, 9, 10, 11, 14, 16, 18, 20, 21, 25, 26, 28], "v1": [2, 5, 7, 9, 13, 18, 20, 21, 22], "kind": [2, 8, 9, 10, 13, 18, 20, 22, 29], "spec": [2, 3, 5, 7, 8, 9, 13, 18, 19, 20, 22, 29], "nodeservic": [2, 13], "broadcastopt": [2, 13], "cover": [2, 20], "everi": [2, 3, 13, 19, 21], "field": [2, 3, 5, 9, 13, 19, 22, 25], "control": [2, 4, 7, 8, 9, 13, 19, 22, 28, 29], "serv": [2, 3, 5, 9, 10, 11, 13, 28], "dedic": [2, 5, 7, 10, 11, 13, 20, 25, 26], "manag": [2, 4, 6, 8, 10, 11, 17, 18, 20, 21, 25, 29], "each": [2, 3, 4, 5, 7, 8, 10, 11, 13, 19, 20, 22, 29], "within": [2, 20, 25], "addition": [2, 13], "defin": [2, 3, 5, 7, 13, 22], "custom": [2, 6, 7, 9, 10, 11, 22], "annot": [2, 9], "incorpor": 2, "which": [2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 17, 18, 19, 20, 22, 29], "might": [2, 8, 17], "further": 2, "tweak": [2, 3], "relat": [2, 6, 13, 25], "object": [2, 3, 9, 13, 29], "selector": [2, 3, 29], "point": [2, 4, 8, 9, 13, 19, 25], "particular": [2, 3, 5, 13, 19, 21], "Such": 2, "doesn": [2, 3, 4, 28, 29], "addit": [2, 5, 7, 8, 11, 29], "ip": [2, 3, 5, 8, 9, 11, 13, 17, 24], "address": [2, 9, 11, 13, 17], "intern": [2, 5, 7], "record": [2, 9], "resolv": [2, 7, 19], "back": [2, 16, 17, 19], "specif": [2, 3, 5, 10, 11, 13, 20, 22, 28, 29], "routabl": 2, "direct": [2, 3, 9, 11], "traffic": [2, 10, 11, 28], "On": [2, 20, 24], "platform": [2, 3, 9, 10, 11, 12], "extern": [2, 5, 8, 9, 17, 25], "load": [2, 13, 16, 17, 22], "balanc": [2, 16], "case": [2, 3, 8, 10, 13, 17, 20, 22, 25, 28, 29], "mai": [2, 9, 13, 14, 16, 17, 19, 20, 21, 22, 25, 29], "reachabl": [2, 9], "public": 2, "via": [2, 3, 5], "kei": [2, 3, 7, 13, 22, 25], "valu": [2, 3, 4, 5, 8, 10, 11, 13, 18, 19, 22], "pair": [2, 3], "through": [2, 3, 5, 10, 11, 13, 22], "entir": [2, 3, 13, 20], "ek": [2, 6, 12, 13], "beta": [2, 21, 22], "scheme": [2, 29], "backend": 2, "protocol": [2, 10], "tcp": [2, 5, 8, 11, 17], "gke": [2, 3, 6, 12, 13, 17], "check": [2, 3, 6, 7, 8, 17, 18, 19, 20, 25, 29], "regard": [2, 8, 11, 13], "learn": [2, 10, 26], "avail": [2, 3, 4, 5, 7, 9, 13, 17, 18, 19, 20, 22, 25, 29], "superset": 2, "impli": 2, "contain": [2, 4, 5, 8, 11, 18, 19, 21, 22, 25, 26, 29], "alloc": [2, 5, 11], "thei": [2, 3, 7, 13, 22, 25], "propag": [2, 3, 8, 13], "externaltrafficpolici": 2, "internaltrafficpolici": 2, "loadbalancerclass": 2, "allocateloadbalancernodeport": 2, "my": [2, 7, 22], "class": [2, 3, 20], "being": [2, 3, 7, 13, 16, 17, 19, 21, 22], "becaus": [2, 3, 7, 13, 17, 25], "help": [2, 3, 6, 25, 26], "cost": 2, "reliabl": 2, "latenc": 2, "secur": [2, 3], "metric": [2, 3, 5], "taken": [2, 18, 19], "By": [2, 4, 5, 20, 22, 25], "default": [2, 3, 4, 5, 7, 13, 17, 18, 20, 22, 24, 25], "statu": [2, 3, 5, 6, 7, 8, 9, 10, 13, 17, 18, 19, 29], "assign": [2, 20], "ingress": [2, 11, 28], "ipaddress": 2, "hostnam": [2, 13], "scenario": 2, "commun": [2, 10, 11, 13], "anoth": [2, 8, 28], "definit": [2, 3, 4, 5, 6, 7, 8, 19, 22, 29], "both": [2, 3, 5, 10, 11, 18], "deploi": [2, 6, 22, 29], "talk": [2, 7, 20, 25], "outsid": [2, 9], "assum": [2, 9, 13, 25], "subnet": [2, 10], "directli": [2, 11], "exclus": [2, 20], "distinct": [2, 10, 11, 13], "interconnect": [2, 10, 11, 12], "facilit": 2, "inter": [2, 12, 13], "connect": [2, 3, 7, 10], "assumpt": 2, "enabl": [2, 3, 4, 7, 10, 11, 13, 14, 16, 19, 22, 24], "establish": [2, 3, 10, 11, 29], "page": [2, 11, 22, 29], "know": 2, "whether": [2, 5, 20, 25], "reach": [2, 7, 9, 19, 28], "sinc": [2, 13], "suffici": 2, "been": [2, 3], "lb": 2, "discov": [2, 13], "resid": [2, 11], "rout": [2, 9], "consequ": 2, "complex": 2, "upon": [2, 10, 11], "ones": [2, 10, 29], "mean": [3, 8], "ideal": 3, "best": 3, "fast": 3, "extra": [3, 25], "detail": [3, 7, 9, 13, 20, 22], "helm": [3, 6, 9, 21], "stabl": [3, 5, 29], "daunt": 3, "error": [3, 4, 7, 19, 22, 25], "prone": 3, "fortun": 3, "wai": [3, 4, 7, 8, 9, 25], "life": [3, 17], "easier": [3, 8, 9, 29], "minikub": [3, 5], "breez": 3, "littl": 3, "bit": [3, 5], "resourc": [3, 6, 7, 8, 9, 10, 11, 13, 14, 18, 20, 22, 28, 29], "6": [3, 18, 20, 21, 22], "Then": [3, 4, 5, 10, 11, 19], "awar": 3, "eval": 3, "env": [3, 25], "manifest": [3, 13, 29], "clone": 3, "either": [3, 5, 7], "upsteam": [3, 5], "self": [3, 5], "sign": [3, 5, 8], "certif": [3, 5, 9, 18], "until": [3, 5, 8, 18, 19, 29], "condit": [3, 5, 8, 9, 13, 18, 20, 29], "issuer": 3, "rollout": [3, 8, 9, 29], "deploy": [3, 5, 7, 9, 11, 12, 13, 18, 19, 22, 29], "app": [3, 5, 9, 13, 18, 19, 29], "webhook": [3, 27, 29], "namespac": [3, 5, 7, 8, 13, 18, 20, 22, 29], "instanc": [3, 4, 5, 7, 8, 9, 10, 11, 13], "feel": [3, 25], "free": [3, 4, 25], "brows": 3, "repres": [3, 13], "our": [3, 8, 13, 20, 21, 25, 26, 29], "below": [3, 7, 8, 9, 10, 11, 13, 18, 20, 22], "import": [3, 4, 21], "successfulli": [3, 9], "extend": [3, 28], "citizen": 3, "nativ": [3, 11], "easi": 3, "someth": [3, 7, 16, 25], "restart": [3, 5, 7, 8, 13, 17, 18, 19, 29], "ag": [3, 5, 7, 8, 17, 29], "9m49": 3, "7m43": 3, "6m46": 3, "note": [3, 7, 9, 22, 29], "pattern": [3, 5, 22, 25], "datacenter_nam": 3, "rack_nam": 3, "instance_numb": 3, "attach": [3, 4, 8, 17, 22, 25, 26], "pick": [3, 13], "resembl": [3, 11], "find": [3, 5, 9, 19, 28, 29], "servic": [3, 5, 8, 9, 11, 16, 17, 28], "inconsequenti": 3, "anyth": 3, "desir": [3, 5, 7, 19, 22], "member": [3, 5, 7, 8, 13, 18, 19, 20, 22], "entri": 3, "l": [3, 5, 7, 8, 9, 18, 25], "state": [3, 5, 7, 9, 13, 17, 19, 22, 25], "current": [3, 5, 6, 9, 10, 11, 13, 19, 22, 25, 28], "squeez": 3, "out": [3, 6, 8, 13, 19, 29], "emploi": 3, "agentvers": [3, 13, 18, 20, 22], "cpuset": [3, 13, 22], "hostnetwork": [3, 22, 28], "result": [3, 8, 22], "sysctl": [3, 13, 22], "increas": [3, 22], "event": 3, "asynchron": 3, "process": [3, 4, 10, 11, 13, 16, 19, 20, 29], "linux": 3, "aio": [3, 13], "max": [3, 13], "nr": [3, 13], "2097152": [3, 13], "instead": [3, 28], "regular": [3, 7], "small": [3, 7, 22], "developermod": [3, 18, 22], "datacent": [3, 5, 6, 7, 10, 11, 17, 18, 20, 25], "port": [3, 5, 8, 9, 10, 17, 18, 22, 29], "8000": 3, "writeisol": [3, 22], "only_rmw_uses_lwt": 3, "whichev": 3, "isol": [3, 22], "forbid_rmw": 3, "between": [3, 10, 11, 22], "level": [3, 7, 22], "cql": [3, 7, 18], "pure": 3, "cqlsh": 3, "shell": [3, 8], "exec": [3, 7, 13, 17, 18, 25], "keyspac": [3, 7, 18, 19, 22], "convent": 3, "python": [3, 20], "svc": [3, 7, 8, 9, 16, 17], "session": 3, "plain": 3, "configmap": 3, "rack": [3, 5, 6, 7, 13, 17, 18, 19, 20], "call": [3, 4, 18, 20, 22, 26, 28, 29], "rest": [3, 7, 25], "config": [3, 4, 7, 10, 11, 13, 22, 25], "statefulset": [3, 5, 8, 9, 19, 29], "rackdc": 3, "tmp": 3, "o": [3, 8, 9, 21, 25], "dry": 3, "replac": [3, 6, 8, 9, 13, 15, 18, 25, 29], "overrid": 3, "prefer_loc": 3, "dc_suffix": 3, "authent": [3, 25], "adjust": [3, 9, 10, 11, 13, 22, 25], "system_auth": [3, 7], "replic": [3, 22], "factor": [3, 22, 25], "node": [3, 5, 6, 7, 8, 9, 16, 18, 19, 22], "inform": [3, 9, 10, 11, 13, 19, 26, 28], "kept": 3, "equal": [3, 13, 20, 22], "fail": [3, 7, 9, 17, 18, 22, 24], "whose": 3, "deni": [3, 11], "product": [3, 7, 8, 9, 13], "networktopologystrategi": 3, "c": [3, 11, 13, 17, 18], "e": [3, 22, 25, 29], "alter": 3, "WITH": 3, "replication_factor": 3, "second": [3, 22], "main": [3, 5, 7, 13], "endpoint": 3, "interact": [3, 16], "thing": 3, "backup": [3, 6, 7, 15, 22, 29], "secret": [3, 5, 9, 13, 22, 25], "popul": 3, "content": [3, 4, 5, 18, 21], "copi": [3, 25], "auto": 3, "empti": [3, 18], "decod": 3, "roll": [3, 5, 6, 8, 13, 18, 19, 29], "prometheu": [3, 5, 6, 7], "grafana": [3, 6], "exist": [3, 7, 8, 13, 19, 21, 25, 29], "introduc": [3, 9, 13, 20], "updat": [3, 5, 7, 9, 11, 22, 29], "add": [3, 5, 7, 8, 11, 13, 16, 17, 18, 29], "append": 3, "choos": [3, 6, 13, 15], "uniqu": [3, 13, 22], "down": [3, 6, 13, 17], "zero": [3, 19], "retriev": [3, 11, 25], "happen": [3, 19, 22], "passwordauthent": 3, "manual": [3, 4, 8, 9, 11, 13, 18, 19, 25, 28, 29], "usernam": [3, 9], "password": [3, 7, 9], "new_replication_factor": 3, "recommend": [3, 9, 13, 29], "along": 3, "mini": 3, "cli": [3, 5, 7, 11], "job": [3, 21, 22], "against": [3, 10, 11], "core": [3, 4, 20], "count": [3, 4, 7], "10": [3, 5, 7, 8, 10, 11, 13, 17, 21], "50": [3, 22], "000": 3, "throttl": [3, 20], "throughput": 3, "30": 3, "op": [3, 8, 13, 18], "sec": 3, "total": 3, "300": 3, "hack": 3, "cass": 3, "gen": 3, "py": 3, "num": [3, 4, 7, 11], "memori": [3, 5, 13, 18, 20, 22], "20g": 3, "50000000": 3, "limit": [3, 5, 7, 13, 18, 20, 22], "30000": 3, "script": [3, 4, 20], "proper": 3, "argument": [3, 7, 22, 25], "h": [3, 22], "usag": 3, "num_job": 3, "scylla_vers": 3, "thread": 3, "per": [3, 22], "connections_per_host": 3, "print": [3, 19], "stdout": 3, "nodeselector": [3, 20], "templat": [3, 8, 9, 13, 18, 29], "messag": [3, 7, 19], "exit": 3, "gb": 3, "ie": 3, "2g": 3, "10000000": 3, "rate": [3, 22], "certain": 3, "eg": 3, "while": 3, "finish": [3, 18], "delet": [3, 7, 8, 17, 19, 29], "walk": [3, 10, 11, 13, 22], "destroi": [3, 7, 13], "data": [3, 4, 7, 9, 13, 17, 18, 19, 22, 23, 29], "examin": [3, 7], "ok": 3, "persist": [4, 7], "guarante": [4, 20], "gcp_user": 4, "gcloud": [4, 11], "format": [4, 7, 11, 19, 22], "gcp_project": 4, "project": [4, 6], "gcp_zone": 4, "west1": [4, 11], "yanniszark": 4, "arrikto": 4, "226716": 4, "zone": [4, 6, 13, 22], "ex": [4, 22], "region": [4, 10, 11, 13, 22], "gcp_region": 4, "cluster_vers": 4, "validmastervers": 4, "systemconfig": 4, "kubeletconfig": 4, "nodepool": 4, "n1": [4, 11], "standard": [4, 11, 28], "8": [4, 7, 9, 11, 21, 22], "purpos": [4, 25], "pd": [4, 11], "ssd": [4, 11], "size": [4, 11, 17, 18, 22], "20": [4, 7, 11, 21], "ubuntu_containerd": [4, 11], "system": [4, 8, 19, 29], "stackdriv": 4, "autoupgrad": [4, 11], "autorepair": [4, 11], "32": 4, "raw": [4, 25], "block": [4, 28], "disabl": [4, 5, 11, 16, 18, 19, 24], "upgrad": [4, 5, 6, 8, 15, 21, 22], "repair": [4, 6, 7, 17, 18, 22], "hard": 4, "timeout": [4, 5, 7, 8, 9], "respect": 4, "pdb": 4, "forc": 4, "comput": [4, 11], "At": [4, 8, 19, 22], "handl": 4, "rbac": 4, "permiss": [4, 7, 8], "credenti": [4, 7, 9, 18], "clusterrolebind": [4, 25], "easiest": 4, "obtain": 4, "gcp": [4, 11], "iam": 4, "web": 4, "interfac": [4, 11], "bind": [4, 22], "clusterrol": [4, 8, 25], "sed": [4, 8, 29], "g": [4, 8, 22, 29], "inject": 4, "match": [4, 9, 20, 21], "compon": [5, 7, 9], "k8": [5, 6, 7, 8, 15, 16, 17, 20, 22], "cluster": [5, 6, 8, 9, 14, 16, 17, 18, 19, 20, 29], "could": 5, "16": [5, 7, 10, 11, 13, 21], "googleapi": [5, 29], "autogener": 5, "60": [5, 7], "execut": [5, 7, 8, 13, 18, 19, 20, 22, 24], "search": 5, "hardwar": 5, "rewrit": 5, "ca": [5, 9], "autom": [5, 6, 7, 13, 29], "databas": [5, 7, 22], "ma": 5, "reason": 5, "interest": 5, "customiz": 5, "download": [5, 18], "hub": [5, 22], "pullpolici": 5, "fullfil": 5, "pull": [5, 22, 25, 29], "url": 5, "compos": [5, 13], "follw": 5, "tag": [5, 8, 18, 19, 21, 22, 29], "ifnotpres": 5, "much": [5, 17], "100m": [5, 13], "128mi": 5, "request": [5, 8, 9, 13, 20, 22, 25, 26], "32mi": 5, "decid": [5, 21], "createselfsignedcertif": 5, "certificatesecretnam": 5, "overwrit": 5, "under": [5, 7, 16, 19], "cours": 5, "scyllaimag": 5, "agentimag": 5, "agent": [5, 7, 13, 22], "express": [5, 22], "5g": 5, "1gi": [5, 9, 18], "gib": [5, 22], "scyllaclust": [5, 6, 8, 9, 13, 14, 18, 19, 20, 22, 25, 29], "customzi": 5, "consist": [5, 7, 13, 18, 20], "applic": [5, 20], "mani": [5, 9, 20, 22, 25], "500m": 5, "500mi": 5, "similarli": [5, 25], "controllerimag": 5, "controllerresourc": 5, "30mi": 5, "20mi": 5, "land": [5, 20], "bootstrap": [5, 17], "isn": 5, "valid": [5, 7, 9, 19, 22, 29], "correctli": 5, "5dbcb54f5c": 5, "vjm4m": 5, "51": [5, 17], "wfjbw": 5, "clusterip": [5, 8, 17], "105": 5, "207": 5, "130": 5, "none": [5, 8, 17], "443": [5, 9], "TO": 5, "replicaset": 5, "669db64dd": 5, "bcm4v": 5, "89": 5, "844ccc56c4": 5, "drbth": 5, "rhwqx": 5, "231": [5, 17], "53": [5, 7], "80": 5, "5090": 5, "9180": [5, 8, 17], "5m58": 5, "4m29": 5, "5m59": 5, "43": [5, 8, 17], "149": 5, "92": 5, "7000": [5, 8, 17], "7001": [5, 8, 17], "7199": [5, 8, 17], "10001": [5, 8, 17], "9042": [5, 8, 17], "9142": [5, 8, 17], "9160": [5, 8, 17], "49": 5, "exactli": [5, 21], "were": 5, "ask": 5, "spin": [5, 7], "servicemonitor": 5, "observ": [5, 19], "managg": 5, "fals": [5, 7, 9, 11, 13, 18, 22], "notic": [5, 9], "prometh": 5, "abl": [5, 10, 28], "scrape": 5, "uninstal": 5, "downscal": 6, "report": [6, 26], "lesson": 6, "univers": 6, "multi": [6, 10, 11, 25], "scale": [6, 19, 25], "dead": 6, "autoh": 6, "topic": [6, 15], "begin": [6, 19], "chart": [6, 9, 21, 29], "expos": [6, 13], "experiment": [6, 9, 20, 29], "procedur": [6, 13, 17, 18, 19, 29], "releas": [6, 29], "contribut": 6, "wide": 7, "predict": 7, "With": [7, 11], "proprietari": 7, "softwar": 7, "licens": 7, "agreement": [7, 19], "spawn": 7, "mission": 7, "watch": 7, "synchron": 7, "regist": [7, 8, 18], "id": [7, 10, 13, 17, 18], "map": [7, 22], "fulli": [7, 13], "unschedul": [7, 14], "bare": [7, 9], "metal": [7, 9], "dc": [7, 13, 22], "37m": 7, "28m": 7, "7bd9f968b9": 7, "w25jw": 7, "info": [7, 25], "2020": [7, 19, 21], "09": [7, 18, 21], "23t11": 7, "25": [7, 8, 13, 21], "27": [7, 13, 21], "882z": 7, "m": [7, 22], "build_dat": 7, "commit": [7, 21], "built_bi": 7, "go_vers": 7, "loglevel": 7, "debug": [7, 25], "apiaddress": 7, "127": 7, "5080": 7, "_trace_id": 7, "lqejv3kdr5gx9m3xq2ynnq": 7, "28": 7, "435z": 7, "26": 7, "238z": 7, "20200816": 7, "76cc4dcc": 7, "pid": 7, "xqhkj0our8e6imdepm62hg": 7, "54": 7, "519z": 7, "tlscertfil": 7, "var": 7, "lib": 7, "scylla_manag": 7, "crt": [7, 9], "tlskeyfil": 7, "tlscafil": 7, "56090": 7, "prometheusscrapeinterv": 7, "5000000000": 7, "56112": 7, "logger": 7, "stderr": 7, "ssl": [7, 9], "localdc": 7, "migratedir": 7, "etc": [7, 9, 20], "migratetimeout": 7, "30000000000": 7, "migratemaxwaitschemaagr": 7, "300000000000": 7, "replicationfactor": 7, "600000000": 7, "tokenawar": 7, "certfil": 7, "usercertfil": 7, "userkeyfil": 7, "healthcheck": 7, "250000000": 7, "ssltimeout": 7, "750000000": 7, "diskspacefreeminperc": 7, "agemax": 7, "43200000000000": 7, "segmentsperrepair": 7, "shardparallelmax": 7, "shardfailedsegmentsmax": 7, "100": [7, 18, 22], "pollinterv": [7, 22], "200000000": 7, "errorbackoff": 7, "shardingignoremsbbit": 7, "config_fil": 7, "mnt": 7, "tutori": 7, "alreadi": [7, 9, 18, 19], "d1d532cd": 7, "49f2": 7, "4c97": 7, "9263": 7, "25126532803b": 7, "sctool": [7, 18], "ti": [7, 17, 18], "next": [7, 19], "400b2723": 7, "eec5": 7, "422a": 7, "b7f3": 7, "236a0e10575b": 7, "23": [7, 8], "sep": 7, "14": 7, "42": 7, "cest": 7, "15": [7, 18], "healthcheck_rest": 7, "28169610": 7, "a969": 7, "4c20": 7, "9d11": 7, "ab7568b8a1bd": 7, "29": 7, "57": 7, "1m": 7, "recur": 7, "healhcheck": 7, "frontend": 7, "altern": [7, 9, 22], "prior": 7, "interv": [7, 22], "1d": [7, 22], "weekli": [7, 22], "locat": [7, 11, 18, 22, 25], "s3": [7, 18, 22], "retent": [7, 22], "7d": [7, 22], "daili": [7, 22], "7": [7, 13, 21], "consult": 7, "bucket": [7, 22], "spot": 7, "275aae7f": 7, "c436": 7, "4fc8": 7, "bcec": 7, "479e65fb8372": 7, "58": 7, "d4946360": 7, "c29d": 7, "4bb4": 7, "8b9d": 7, "619ada495c2a": 7, "38": 7, "shortli": 7, "progress": [7, 9, 13, 18], "utc": [7, 18], "durat": [7, 18, 22, 25], "69": 7, "06": [7, 21], "system_distribut": 7, "00": 7, "system_trac": 7, "present": [7, 10], "wasn": 7, "cannot": [7, 20], "due": [7, 13, 14, 18, 22], "lack": [7, 22], "target": [7, 10, 18, 20, 29], "62": [7, 17], "attempt": 7, "correct": [7, 9], "107": [7, 13], "193": 7, "33": 7, "109": 7, "197": 7, "00000000": 7, "0000": 7, "000000000000": 7, "adhoc": 7, "retri": [7, 19, 22], "2b9dbe8c": 7, "9daa": 7, "4703": 7, "a66d": 7, "c29f63a917c8": 7, "infinit": 7, "appear": 7, "solv": [8, 29], "disambigu": [8, 29], "backward": [8, 29], "incompat": [8, 29], "involv": 8, "detach": 8, "period": 8, "noth": 8, "garbag": 8, "collect": [8, 9, 26], "shouldn": [8, 17], "caus": [8, 16, 17, 19, 20], "downtim": 8, "consid": 8, "hacki": 8, "box": 8, "stage": [8, 19], "whole": [8, 19], "question": 8, "welcom": 8, "slack": 8, "channel": [8, 10], "sequenti": 8, "30m": [8, 29], "cert": 8, "offici": [8, 22], "websit": 8, "extract": [8, 13], "customresourcedefinit": [8, 29], "previou": [8, 19], "v1alpha1": [8, 9, 20, 29], "uuid": 8, "newli": 8, "metadata": [8, 9, 10, 13, 18, 20, 22], "uid": 8, "12a3678d": 8, "8511": 8, "4c9c": 8, "8a48": 8, "fa78d3992694": 8, "somewher": 8, "grant": 8, "lookup": 8, "patch": [8, 13, 18, 19, 29], "json": [8, 13, 18], "rule": [8, 10, 28], "apigroup": 8, "verb": 8, "amend": 8, "109m": 8, "96": 8, "66": 8, "22": [8, 21], "108m": 8, "246": 8, "106m": 8, "ownerrefer": 8, "column": 8, "lower": [8, 22], "110m": 8, "107m": 8, "st": [8, 29], "104m": 8, "bound": [8, 14, 17, 20], "old": [8, 17, 29], "boot": [8, 19], "600": 8, "initi": [8, 13, 22], "initcontain": 8, "bump": 8, "endpointsselector": 9, "matchlabel": [9, 13], "ident": 9, "volumeclaimtempl": 9, "webinterfac": 9, "ingressclassnam": 9, "dnsdomain": 9, "passthrough": 9, "futur": [9, 10, 11], "third": 9, "parti": 9, "skip": [9, 25], "5m": 9, "met": [9, 13, 18], "degrad": [9, 13, 18], "revis": 9, "65b89d55bb": 9, "matter": 9, "packet": [9, 20], "tl": [9, 18], "sni": 9, "caller": 9, "properli": [9, 19, 28, 29], "real": 9, "grafana_serving_cert": 9, "index": [9, 13], "base64": [9, 13], "d": [9, 13, 22, 29], "grafana_us": 9, "admin": [9, 25], "grafana_password": 9, "appropri": 9, "often": [9, 22, 28], "wildcard": 9, "mydomain": 9, "cname": 9, "similar": [9, 10, 13, 25], "curl": 9, "dev": [9, 22], "null": 9, "w": 9, "http_code": 9, "cacert": 9, "echo": 9, "200": 9, "beyond": [9, 28], "unless": [9, 25], "ingress_port": 9, "loadbalanc": 9, "ingress_ip": 9, "slightli": [9, 22], "conveni": 9, "internal_ip": 9, "external_ip": 9, "rang": [9, 10, 11, 22], "item": 9, "eq": 9, "internalip": 9, "easili": [10, 11], "infrastructur": [10, 11, 13], "tailor": [10, 11], "simplic": [10, 11, 13], "predefin": [10, 11, 25], "throughout": [10, 11, 13], "exemplari": [10, 11], "v1alpha5": 10, "clusterconfig": 10, "availabilityzon": 10, "cidr": [10, 11], "context": [10, 11, 20, 25], "flag": [10, 11, 14, 18, 25, 29], "return": [10, 11, 16], "workload": [10, 11, 20], "volum": [10, 11, 13, 22, 25], "provision": [10, 11, 13], "non": [10, 13, 18, 19], "overlap": [10, 11], "ipv4": [10, 11], "2a": [10, 13], "2b": [10, 13], "2c": [10, 13], "172": [10, 11, 13, 17], "analog": [10, 11], "known": [10, 23], "pcx": 10, "08077dcc008fbbab6": 10, "privat": 10, "destin": 10, "given": [10, 17, 22, 25], "send": [10, 25], "preconfigur": 10, "omit": 10, "readabl": [10, 22], "publicroutet": 10, "flow": 10, "inbound": 10, "share": [10, 11, 20, 22], "correspond": [10, 11, 22], "clustersharednodesecuritygroup": 10, "td05v9evu3b8": 10, "1fr9ydlu0ve7m": 10, "guidanc": [10, 11], "googl": 11, "virtual": 11, "secondari": 11, "east1": [11, 16], "17": [11, 21], "18": [11, 13], "alia": 11, "subnetwork": 11, "permit": 11, "model": [11, 22], "hash": 11, "filter": 11, "prioriti": 11, "f17db261": 11, "1000": 11, "udp": 11, "icmp": 11, "esp": 11, "ah": 11, "sctp": 11, "0bb60902": 11, "build": [12, 13, 21], "discuss": 13, "unrel": 13, "expect": [13, 29], "meet": [13, 20], "topologi": 13, "storageclass": [13, 22], "11": [13, 18, 21], "machineri": 13, "scyladb": 13, "intervent": 13, "human": [13, 22], "notabl": 13, "leav": [13, 17, 20], "behind": 13, "mechan": 13, "externalse": 13, "binari": [13, 25], "paramet": [13, 22], "understood": 13, "contact": 13, "ring": 13, "join": [13, 17], "function": [13, 21, 28], "enhanc": 13, "propos": 13, "subset": [13, 25], "scyllaclus": 13, "headless": 13, "howev": [13, 20], "context_dc1": 13, "context_dc2": 13, "correspondingli": 13, "accordingli": 13, "across": [13, 20, 22], "center": 13, "dc1": [13, 22], "automaticorphanednodecleanup": [13, 14, 22], "storageclassnam": [13, 22], "1800g": 13, "agentresourc": [13, 20, 22], "250m": 13, "56g": 13, "placement": [13, 20, 22], "podantiaffin": [13, 22], "requiredduringschedulingignoredduringexecut": [13, 22], "topologykei": 13, "labelselector": 13, "nodeaffin": [13, 22], "nodeselectorterm": [13, 22], "matchexpress": [13, 22], "effect": [13, 22], "un": [13, 17], "nodetool": [13, 17], "normal": [13, 17], "move": [13, 17, 19, 20], "token": [13, 17, 22, 25], "70": 13, "195": 13, "290": 13, "kb": [13, 17], "256": [13, 17], "494277b9": 13, "121c": 13, "4af9": 13, "bd63": 13, "3d0a7b9305f7": 13, "59": 13, "24": [13, 18], "559": 13, "a3a98e08": 13, "0dfd": 13, "4a25": 13, "a96a": 13, "c5ab2f47eb37": 13, "19": [13, 21], "237": 13, "64b6292a": 13, "327f": 13, "4128": 13, "852a": 13, "6004039f402e": 13, "ephemer": 13, "natur": 13, "ill": 13, "advis": [13, 25, 28], "high": 13, "likelihood": 13, "undesir": 13, "startup": 13, "fallback": 13, "peer": 13, "unreach": 13, "domain": [13, 22], "sheer": 13, "util": 13, "dc2": 13, "705": 13, "764": 13, "634": 13, "39": 13, "209": 13, "336": 13, "7c30ea55": 13, "7a4f": 13, "4d93": 13, "86f7": 13, "c881772ebe62": 13, "759": 13, "665dde7e": 13, "e420": 13, "4db3": 13, "8c54": 13, "ca71efd39b2": 13, "87": 13, "503": 13, "c19c89cb": 13, "e24c": 13, "4062": 13, "9df4": 13, "2aa90ab29a99": 13, "cr": 13, "random": 13, "auth": 13, "auth_token": 13, "84qtsfvm98qzmps8s65zr2vtpb8rg4sdzcbg4pbmg2pfhxwpg952654gj86tzdljfqnsghndljm58mmhpmwfgpsvjx2kkmnns8bnblmgkbl9n8l9f64rs6tcvttm7kmf": 13, "stringdata": 13, "forceredeploymentreason": [13, 18], "sync": [13, 17], "incid": 14, "explicit": 14, "becom": [14, 19, 21], "pvc": 14, "affin": 14, "hi": 14, "cleanup": [15, 19, 22], "lost": 15, "mainten": [15, 19], "restor": [15, 19, 29], "probe": [16, 29], "failur": [16, 17, 19, 22], "live": 16, "succe": 16, "registri": 16, "stai": 16, "aliv": 16, "turn": [16, 19, 29], "bring": [16, 17, 19, 29], "front": 16, "possibl": [17, 22], "stream": 17, "bandwidth": 17, "125": 17, "110": 17, "74": 17, "63": 17, "8ebd6114": 17, "969c": 17, "44af": 17, "a978": 17, "87a4a6c65c3": 17, "189": 17, "91": 17, "03": [17, 21], "35d0cb19": 17, "35ef": 17, "482b": 17, "92a4": 17, "b63eee4527e5": 17, "77": 17, "1ffa7a82": 17, "c41c": 17, "4706": 17, "8f5f": 17, "4d45a39c7003": 17, "identifi": [17, 18], "3h12m": 17, "3h11m": 17, "3h5m": 17, "drain": [17, 19], "b4b390a1": 17, "6j12": 17, "ignor": 17, "daemonset": [17, 20], "pend": 17, "3h21m": 17, "3h19m": 17, "8m14": 17, "recreat": [17, 29], "3h27m": 17, "3h25m": 17, "9": [17, 18, 19, 21, 29], "store": [17, 18, 22], "visibl": 17, "191": 17, "fresh": [18, 29], "gate": 18, "automatictlscertif": 18, "arg": 18, "foo": 18, "af1dd5cd": 18, "0406": 18, "4974": 18, "949f": 18, "dc9842980080": 18, "ebd82268": 18, "efb7": 18, "407e": 18, "a540": 18, "3619ae053778": 18, "snapshot": [18, 19, 22], "cluster_id": 18, "backup_loc": 18, "ff36d7e0": 18, "af2": 18, "458c": 18, "afe6": 18, "868e0f3396b2": 18, "sm_20240105115931utc": 18, "409mib": 18, "system_schema": [18, 19], "tabl": [18, 21, 22], "schema": [18, 19], "snapshot_tag": 18, "57228c52": 18, "7cf6": 18, "4271": 18, "8c8d": 18, "d446ff160747": 18, "0dd20cdf": 18, "abc4": 18, "11ee": 18, "951c": 18, "6e7993cf42": 18, "05": [18, 21], "jan": 18, "02": [18, 21], "success": 18, "214": 18, "150k": 18, "suggest": 18, "63642069": 18, "bed5": 18, "4def": 18, "ba0f": 18, "68c49e47ace1": 18, "ab015cef": 18, "abc8": 18, "9521": 18, "48": 18, "04": [18, 21], "post": 18, "intens": [18, 22], "parallel": [18, 19, 22], "detect": 19, "semant": 19, "nightli": 19, "so_data_20201228135002utc": 19, "validate_upgrad": 19, "so_system_20201228135002utc": 19, "underli": [19, 22], "ondelet": 19, "upgradestrategi": 19, "trace": 19, "displai": 19, "begin_upgrad": 19, "check_schema_agr": 19, "minut": 19, "create_system_backup": 19, "find_next_rack": 19, "decis": 19, "upgrade_image_in_pod_spec": 19, "find_next_nod": 19, "enable_maintenance_mod": 19, "drain_nod": 19, "backup_data": 19, "disable_maintenance_mod": 19, "delete_pod": 19, "clear_data_backup": 19, "clear_system_backup": 19, "restore_upgrade_strategi": 19, "finish_upgrad": 19, "recov": 19, "stuck": 19, "refus": 19, "replica": [19, 22], "root": 19, "sstabl": 19, "left": [19, 22], "suppos": 20, "perftun": 20, "optmiz": 20, "kernel": 20, "spread": 20, "irq": 20, "immedi": 20, "effic": 20, "pin": [20, 22, 29], "interrupt": 20, "One": 20, "switch": 20, "coupl": 20, "daemon": 20, "space": 20, "advantag": 20, "special": 20, "qo": 20, "doubl": 20, "cf": 20, "quota": 20, "enforc": 20, "around": 20, "distribut": 20, "part": [20, 22], "fulfil": 20, "receiv": 20, "500gi": 20, "1g": 20, "16g": 20, "aim": 21, "ship": 21, "approxim": 21, "week": 21, "advisori": 21, "hit": [21, 25], "code": [21, 29], "freez": 21, "everyon": 21, "08": 21, "07": 21, "01": 21, "2022": 21, "2021": 21, "21": 21, "elig": 21, "situat": 21, "assess": 21, "action": 21, "branch": [21, 29], "trigger": 21, "publish": 21, "artifact": 21, "e2": 21, "suit": [21, 28], "vx": 21, "y": 21, "x": 21, "rc": 21, "ga": 21, "aren": 21, "scratch": [21, 29], "rather": 21, "candid": 21, "qualiti": 21, "qa": 21, "sing": 21, "sha": 21, "Be": 21, "cri": 21, "v1alpha2": 21, "ratelimit": 22, "500g": 22, "32gi": 22, "unset": 22, "agentrepositori": 22, "orphan": 22, "genericupgrad": 22, "failurestrategi": 22, "poll": 22, "sent": 22, "kube": [22, 25], "apiserv": [22, 28], "affect": [22, 25], "overal": 22, "spent": 22, "scyllaarg": 22, "dnspolici": 22, "moment": 22, "schedul": 22, "startdat": 22, "rfc3339": 22, "3d2h10m": 22, "numretri": 22, "glob": 22, "otherdc": 22, "exclud": 22, "failfast": 22, "stop": 22, "shard": 22, "max_repair_ranges_in_parallel": 22, "integ": 22, "higher": 22, "faster": 22, "impact": 22, "granular": 22, "resum": 22, "row": 22, "decim": 22, "percent": 22, "string": 22, "float": 22, "runtim": [22, 25], "rf": 22, "formula": 22, "calcul": 22, "table_prefix_": 22, "smalltablethreshold": 22, "threshold": 22, "mib": 22, "tib": 22, "1gib": 22, "alphanumer": 22, "dot": 22, "charact": 22, "forbidden": 22, "gc": 22, "megabyt": 22, "snapshotparallel": 22, "global": 22, "uploadparallel": 22, "confus": 22, "ram": 22, "minimum": 22, "amount": 22, "volumemount": 22, "agentvolumemount": 22, "scyllaconfig": 22, "scyllaagentconfig": 22, "subfield": 22, "podaffin": 22, "overview": 23, "troubleshoot": 23, "gather": 23, "8th": 24, "migrat": [24, 29], "008_": 24, "hairpin": 24, "sudo": 24, "docker0": 24, "promisc": 24, "embed": [25, 26], "goe": 25, "wrong": 25, "censor": 25, "sensit": 25, "That": 25, "said": 25, "review": 25, "archiv": [25, 26], "suppli": 25, "kubeconfig": 25, "There": [25, 28, 29], "slight": 25, "deviat": 25, "selinux": 25, "mention": 25, "lsetxattr": 25, "try": 25, "plugin": 25, "view": 25, "minifi": 25, "user_nam": 25, "few": 25, "serviceaccount": 25, "must_gather_token": 25, "1h": 25, "mktemp": [25, 29], "yq": 25, "mikefarah": 25, "rm": 25, "ro": 25, "pwd": 25, "workspac": 25, "workdir": 25, "namespace_with_broken_scyllaclust": 25, "still": 25, "wouldn": 25, "enough": 25, "administr": 26, "paid": 26, "aris": 26, "visit": 26, "unfortun": 28, "sdn": 28, "plane": [28, 29], "firewal": 28, "conform": 28, "break": 28, "workaround": 28, "reconfigur": 28, "5871": 29, "7735": 29, "release_nam": 29, "tmpdir": 29, "untar": 29, "untardir": 29, "printf": 29, "xarg": 29, "minor": 29, "symlink": 29, "brought": 29, "lot": 29, "mutatingwebhookconfigur": 29, "mutat": 29, "validatingwebhookconfigur": 29, "95m": 29, "livenessprob": 29, "httpget": 29, "healthz": 29, "8080": 29, "readinessprob": 29, "retainkei": 29, "readyz": 29, "cat": 29, "preserv": 29}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"contribut": 0, "scylla": [0, 1, 3, 4, 5, 6, 7, 13, 15, 17, 19, 22, 24, 29], "oper": [0, 1, 3, 4, 5, 6, 9, 10, 11, 15, 29], "prerequisit": [0, 1, 3, 4, 5, 7, 9, 10, 11, 13, 25], "initi": [0, 3], "setup": [0, 1, 4], "creat": [0, 1, 3, 4, 10, 11], "fork": 0, "clone": 0, "your": [0, 26], "add": 0, "upstream": 0, "remot": 0, "develop": 0, "build": [0, 10, 11], "project": 0, "branch": 0, "updat": [0, 10], "submit": 0, "pull": 0, "request": 0, "commit": 0, "histori": 0, "messag": 0, "deploi": [1, 3, 4, 5, 7, 9, 10, 11, 12, 13], "ek": [1, 10, 28], "tl": [1, 4, 5], "dr": [1, 4, 5], "walkthrough": [1, 4], "configur": [1, 3, 4, 10, 11], "environ": [1, 4], "variabl": [1, 4], "an": [1, 9], "cluster": [1, 2, 3, 4, 7, 10, 11, 12, 13, 22, 25, 26, 28], "instal": [1, 5, 28], "script": 1, "third": 1, "parti": 1, "depend": 1, "scylladb": [1, 4, 10, 11, 12, 13], "set": [1, 3, 4, 22], "up": [1, 3, 4, 7, 24], "node": [1, 2, 4, 10, 11, 13, 14, 15, 17, 20], "local": [1, 3, 4], "volum": [1, 4], "provision": [1, 4], "access": [1, 3, 4, 9], "databas": [1, 3, 4], "delet": [1, 4], "expos": 2, "scyllaclust": [2, 3], "option": 2, "servic": 2, "templat": 2, "headless": 2, "type": 2, "clusterip": 2, "loadbalanc": 2, "broadcast": 2, "podip": [2, 13], "serviceclusterip": 2, "serviceloadbalanceringress": 2, "deploy": 2, "exampl": 2, "In": 2, "onli": 2, "vpc": [2, 10, 11], "client": 2, "multi": [2, 12, 13], "internet": 2, "kubernet": [3, 4, 7, 10, 11, 12, 13, 20], "run": [3, 10, 11, 25], "download": 3, "cert": [3, 5], "manag": [3, 5, 7, 9, 13, 22, 24], "host": 3, "network": [3, 10, 11, 13], "contain": 3, "kernel": 3, "paramet": 3, "altern": 3, "agent": 3, "auth": 3, "token": 3, "monitor": [3, 5, 9], "scale": 3, "benchmark": 3, "cassandra": 3, "stress": 3, "clean": [3, 7], "troubleshoot": [3, 7, 26, 27, 28], "gke": [4, 11, 28], "googl": 4, "engin": 4, "yourself": 4, "admin": 4, "stack": 5, "us": [5, 9, 13, 15], "helm": [5, 29], "chart": 5, "repositori": 5, "imag": 5, "resourc": [5, 25], "webhook": [5, 28], "custom": [5, 28], "control": 5, "result": 5, "cleanup": [5, 14], "document": 6, "architectur": 7, "registr": 7, "task": 7, "schedul": [7, 21], "version": [8, 19], "migrat": 8, "v0": [8, 29], "3": [8, 29], "0": [8, 29], "v1": [8, 29], "procedur": 8, "requir": 9, "prometheu": 9, "wait": 9, "roll": 9, "out": 9, "haproxi": 9, "ingress": 9, "scylladbmonitor": [9, 13], "grafana": 9, "connect": 9, "through": 9, "resolv": 9, "domain": 9, "unresolv": 9, "variant": 9, "externalip": 9, "nodeport": 9, "multipl": [10, 11, 13], "amazon": 10, "inter": [10, 11], "first": [10, 11, 13], "prepar": [10, 11], "second": [10, 11, 13], "peer": 10, "rout": 10, "tabl": 10, "secur": 10, "group": 10, "subnet": 11, "firewal": 11, "rule": 11, "datacent": [12, 13, 22], "interconnect": 13, "extern": 13, "seed": 13, "context": 13, "retriev": 13, "automat": 14, "replac": [14, 17], "case": 14, "when": 14, "k8": 14, "i": 14, "lost": 14, "mainten": 16, "mode": 16, "dead": 17, "restor": 18, "from": 18, "backup": 18, "upgrad": [19, 29], "perform": 20, "tune": 20, "releas": 21, "support": [21, 23, 26], "backport": 21, "polici": 21, "ci": 21, "cd": 21, "autom": 21, "promot": 21, "gener": 21, "avail": 21, "matrix": 21, "crd": 22, "sampl": 22, "explan": 22, "rack": 22, "known": 24, "issu": [24, 26, 28], "doe": 24, "boot": 24, "minikub": 24, "truncat": 24, "queri": 24, "work": 24, "gather": [25, 26], "data": [25, 26], "must": 25, "podman": 25, "docker": 25, "limit": 25, "particular": 25, "namespac": 25, "collect": 25, "everi": 25, "overview": 26, "get": 26, "about": 26, "cni": 28, "privat": 28, "via": 29, "kubectl": 29, "2": 29, "1": 29}, "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": {"Node operations using Scylla Operator": [[15, "node-operations-using-scylla-operator"]], "Replacing a Scylla node": [[17, "replacing-a-scylla-node"]], "Replacing a dead node": [[17, "replacing-a-dead-node"]], "Maintenance mode": [[16, "maintenance-mode"]], "Automatic cleanup and replacement in case when k8s node is lost": [[14, "automatic-cleanup-and-replacement-in-case-when-k8s-node-is-lost"]], "Upgrading version of Scylla": [[19, "upgrading-version-of-scylla"]], "Restore from backup": [[18, "restore-from-backup"]], "Performance tuning": [[20, "performance-tuning"]], "Node tuning": [[20, "node-tuning"]], "Kubernetes tuning": [[20, "kubernetes-tuning"]], "Known issues": [[24, "known-issues"]], "Scylla Manager does not boot up on Minikube": [[24, "scylla-manager-does-not-boot-up-on-minikube"]], "TRUNCATE queries does not work on Minikube": [[24, "truncate-queries-does-not-work-on-minikube"]], "Support overview": [[26, "support-overview"]], "Get support": [[26, "get-support"]], "Troubleshooting issues": [[26, "troubleshooting-issues"]], "Gather data about your cluster": [[26, "gather-data-about-your-cluster"]], "Support": [[23, "support"]], "Troubleshooting": [[27, "troubleshooting"], [7, "troubleshooting"], [3, "troubleshooting"]], "Releases": [[21, "releases"]], "Schedule": [[21, "schedule"]], "Supported releases": [[21, "supported-releases"]], "Backport policy": [[21, "backport-policy"]], "CI/CD": [[21, "ci-cd"]], "Automated promotions": [[21, "automated-promotions"]], "Generally available": [[21, "generally-available"]], "Support matrix": [[21, "support-matrix"]], "Scylla Cluster CRD": [[22, "scylla-cluster-crd"]], "Sample": [[22, "sample"]], "Settings Explanation": [[22, "settings-explanation"]], "Cluster Settings": [[22, "cluster-settings"]], "Scylla Manager settings": [[22, "scylla-manager-settings"]], "Datacenter Settings": [[22, "datacenter-settings"]], "Rack Settings": [[22, "rack-settings"]], "Gathering data with must-gather": [[25, "gathering-data-with-must-gather"]], "Running must-gather": [[25, "running-must-gather"]], "Prerequisites": [[25, "prerequisites"], [9, "prerequisites"], [11, "prerequisites"], [13, "prerequisites"], [7, "prerequisites"], [10, "prerequisites"], [0, "prerequisites"], [5, "prerequisites"], [4, "prerequisites"], [1, "prerequisites"], [3, "prerequisites"]], "Podman": [[25, "podman"]], "Docker": [[25, "docker"]], "Limiting must-gather to a particular namespace": [[25, "limiting-must-gather-to-a-particular-namespace"]], "Collecting every resource in the cluster": [[25, "collecting-every-resource-in-the-cluster"]], "Monitoring": [[9, "monitoring"], [5, "monitoring"]], "Deploy managed monitoring": [[9, "deploy-managed-monitoring"]], "Requirements": [[9, "requirements"]], "Deploy Prometheus Operator": [[9, "deploy-prometheus-operator"]], "Wait for Prometheus Operator to roll out": [[9, "wait-for-prometheus-operator-to-roll-out"]], "Deploy HAProxy Ingress": [[9, "deploy-haproxy-ingress"]], "Wait for HAProxy Ingress to roll out": [[9, "wait-for-haproxy-ingress-to-roll-out"]], "Deploy ScyllaDBMonitoring": [[9, "deploy-scylladbmonitoring"]], "Wait for ScyllaDBMonitoring to roll out": [[9, "wait-for-scylladbmonitoring-to-roll-out"]], "Wait for Prometheus to roll out": [[9, "wait-for-prometheus-to-roll-out"]], "Wait for Grafana to roll out": [[9, "wait-for-grafana-to-roll-out"]], "Accessing Grafana": [[9, "accessing-grafana"]], "Connecting through Ingress using a resolvable domain": [[9, "connecting-through-ingress-using-a-resolvable-domain"]], "Connecting through Ingress using an unresolvable domain": [[9, "connecting-through-ingress-using-an-unresolvable-domain"]], "Variants": [[9, "variants"]], "Ingress ExternalIP": [[9, "ingress-externalip"]], "Ingress NodePort": [[9, "ingress-nodeport"]], "Connection": [[9, "connection"]], "Deploying multi-datacenter ScyllaDB clusters in Kubernetes": [[12, "deploying-multi-datacenter-scylladb-clusters-in-kubernetes"]], "Version migrations": [[8, "version-migrations"]], "v0.3.0 -> v1.0.0 migration": [[8, "v0-3-0-v1-0-0-migration"]], "Procedure": [[8, "procedure"]], "Build multiple GKE clusters with inter-Kubernetes networking": [[11, "build-multiple-gke-clusters-with-inter-kubernetes-networking"]], "Create and configure a VPC network": [[11, "create-and-configure-a-vpc-network"]], "Create the VPC network": [[11, "create-the-vpc-network"]], "Create VPC network subnets": [[11, "create-vpc-network-subnets"]], "Create GKE clusters": [[11, "create-gke-clusters"]], "Create the first GKE cluster": [[11, "create-the-first-gke-cluster"]], "Deploy ScyllaDB Operator": [[11, "deploy-scylladb-operator"], [10, "deploy-scylladb-operator"]], "Prepare nodes for running ScyllaDB": [[11, "prepare-nodes-for-running-scylladb"], [10, "prepare-nodes-for-running-scylladb"]], "Create the second GKE cluster": [[11, "create-the-second-gke-cluster"]], "Configure the firewall rules": [[11, "configure-the-firewall-rules"]], "Deploy a multi-datacenter ScyllaDB cluster in multiple interconnected Kubernetes clusters": [[13, "deploy-a-multi-datacenter-scylladb-cluster-in-multiple-interconnected-kubernetes-clusters"]], "Multi Datacenter ScyllaDB Cluster": [[13, "multi-datacenter-scylladb-cluster"]], "External seeds": [[13, "external-seeds"]], "Networking": [[13, "networking"]], "Deploy a multi-datacenter ScyllaDB Cluster": [[13, "deploy-a-multi-datacenter-scylladb-cluster"]], "Using context": [[13, "using-context"]], "Deploy the first datacenter": [[13, "deploy-the-first-datacenter"]], "Retrieve PodIPs of ScyllaDB nodes for use as external seeds": [[13, "retrieve-podips-of-scylladb-nodes-for-use-as-external-seeds"]], "Deploy the second datacenter": [[13, "deploy-the-second-datacenter"]], "Scylla Manager": [[13, "scylla-manager"], [5, "scylla-manager"]], "ScyllaDBMonitoring": [[13, "scylladbmonitoring"]], "Deploying Scylla Manager on a Kubernetes Cluster": [[7, "deploying-scylla-manager-on-a-kubernetes-cluster"]], "Architecture": [[7, "architecture"]], "Deploy Scylla Manager": [[7, "deploy-scylla-manager"]], "Cluster registration": [[7, "cluster-registration"]], "Task scheduling": [[7, "task-scheduling"]], "Clean Up": [[7, "clean-up"], [3, "clean-up"]], "Build multiple Amazon EKS clusters with inter-Kubernetes networking": [[10, "build-multiple-amazon-eks-clusters-with-inter-kubernetes-networking"]], "Create EKS clusters": [[10, "create-eks-clusters"]], "Create the first EKS cluster": [[10, "create-the-first-eks-cluster"]], "Create the second EKS cluster": [[10, "create-the-second-eks-cluster"]], "Configure the network": [[10, "configure-the-network"]], "Create VPC peering": [[10, "create-vpc-peering"]], "Update route tables": [[10, "update-route-tables"]], "Update security groups": [[10, "update-security-groups"]], "Contributing to Scylla Operator": [[0, "contributing-to-scylla-operator"]], "Initial Setup": [[0, "initial-setup"]], "Create a Fork": [[0, "create-a-fork"]], "Clone Your Fork": [[0, "clone-your-fork"]], "Add Upstream Remote": [[0, "add-upstream-remote"]], "Development": [[0, "development"]], "Building the project": [[0, "building-the-project"]], "Create a Branch": [[0, "create-a-branch"]], "Updating Your Fork": [[0, "updating-your-fork"]], "Submitting a Pull Request": [[0, "submitting-a-pull-request"]], "Commit History": [[0, "commit-history"]], "Commit messages": [[0, "commit-messages"]], "Submitting": [[0, "submitting"]], "Exposing ScyllaCluster": [[2, "exposing-scyllacluster"]], "Expose Options": [[2, "expose-options"]], "Node Service Template": [[2, "node-service-template"]], "Headless Type": [[2, "headless-type"]], "ClusterIP Type": [[2, "clusterip-type"]], "LoadBalancer Type": [[2, "loadbalancer-type"]], "Broadcast Options": [[2, "broadcast-options"]], "PodIP Type": [[2, "podip-type"]], "ServiceClusterIP Type": [[2, "serviceclusterip-type"]], "ServiceLoadBalancerIngress Type": [[2, "serviceloadbalanceringress-type"]], "Deployment Examples": [[2, "deployment-examples"]], "In-cluster only": [[2, "in-cluster-only"]], "In-cluster node-to-node, VPC clients-to-nodes": [[2, "in-cluster-node-to-node-vpc-clients-to-nodes"]], "Multi VPC": [[2, "multi-vpc"]], "Internet": [[2, "internet"]], "Deploying Scylla stack using Helm Charts": [[5, "deploying-scylla-stack-using-helm-charts"]], "TL;DR": [[5, "tl-dr"]], "Deploy Cert Manager": [[5, "deploy-cert-manager"], [3, "deploy-cert-manager"]], "Helm Chart repository": [[5, "helm-chart-repository"]], "Scylla Operator Chart": [[5, "scylla-operator-chart"]], "image": [[5, "image"]], "resources": [[5, "resources"]], "webhook": [[5, "webhook"]], "Customization": [[5, "customization"], [5, "id1"], [5, "id3"]], "Installation": [[5, "installation"], [5, "id2"], [5, "id4"]], "Scylla Helm Chart": [[5, "scylla-helm-chart"]], "Scylla Manager Helm Chart": [[5, "scylla-manager-helm-chart"]], "Scylla Manager Controller": [[5, "scylla-manager-controller"]], "Scylla": [[5, "scylla"]], "Results": [[5, "results"]], "Cleanup": [[5, "cleanup"]], "Deploying Scylla on GKE": [[4, "deploying-scylla-on-gke"]], "TL;DR;": [[4, "tl-dr"], [1, "tl-dr"]], "Walkthrough": [[4, "walkthrough"], [1, "walkthrough"]], "Google Kubernetes Engine Setup": [[4, "google-kubernetes-engine-setup"]], "Configure environment variables": [[4, "configure-environment-variables"], [1, "configure-environment-variables"]], "Creating a GKE cluster": [[4, "creating-a-gke-cluster"]], "Setting Yourself as cluster-admin": [[4, "setting-yourself-as-cluster-admin"]], "Deploying ScyllaDB Operator": [[4, "deploying-scylladb-operator"], [1, "deploying-scylladb-operator"]], "Setting up nodes for ScyllaDB": [[4, "setting-up-nodes-for-scylladb"], [1, "setting-up-nodes-for-scylladb"]], "Deploying Local Volume Provisioner": [[4, "deploying-local-volume-provisioner"], [1, "deploying-local-volume-provisioner"]], "Deploy Scylla cluster": [[4, "deploy-scylla-cluster"]], "Deploying ScyllaDB": [[4, "deploying-scylladb"], [1, "deploying-scylladb"]], "Accessing the database": [[4, "accessing-the-database"], [1, "accessing-the-database"]], "Deleting a GKE cluster": [[4, "deleting-a-gke-cluster"]], "Scylla Operator Documentation": [[6, "scylla-operator-documentation"]], "Deploying Scylla on EKS": [[1, "deploying-scylla-on-eks"]], "EKS Setup": [[1, "eks-setup"]], "Creating an EKS cluster": [[1, "creating-an-eks-cluster"]], "Installing script third party dependencies": [[1, "installing-script-third-party-dependencies"]], "Deleting an EKS cluster": [[1, "deleting-an-eks-cluster"]], "Deploying Scylla on a Kubernetes Cluster": [[3, "deploying-scylla-on-a-kubernetes-cluster"]], "Running locally": [[3, "running-locally"]], "Download Scylla Operator": [[3, "download-scylla-operator"]], "Deploy Scylla Operator": [[3, "deploy-scylla-operator"]], "Create and Initialize a Scylla Cluster": [[3, "create-and-initialize-a-scylla-cluster"]], "Configure host networking": [[3, "configure-host-networking"]], "Configure container kernel parameters": [[3, "configure-container-kernel-parameters"]], "Deploying Alternator": [[3, "deploying-alternator"]], "Accessing the Database": [[3, "accessing-the-database"]], "Configure Scylla": [[3, "configure-scylla"]], "Configure Scylla Manager Agent": [[3, "configure-scylla-manager-agent"]], "Scylla Manager Agent auth token": [[3, "scylla-manager-agent-auth-token"]], "Set up monitoring": [[3, "set-up-monitoring"]], "Scale a ScyllaCluster": [[3, "scale-a-scyllacluster"]], "Benchmark with cassandra-stress": [[3, "benchmark-with-cassandra-stress"]], "Upgrade of Scylla Operator": [[29, "upgrade-of-scylla-operator"]], "Upgrade via Helm": [[29, "upgrade-via-helm"]], "Upgrade via kubectl": [[29, "upgrade-via-kubectl"]], "v1.2.0 -> v1.3.0": [[29, "v1-2-0-v1-3-0"]], "v1.1.0 -> v1.2.0": [[29, "v1-1-0-v1-2-0"]], "v1.0.0 -> v1.1.0": [[29, "v1-0-0-v1-1-0"]], "v0.3.0 -> v1.0.0": [[29, "v0-3-0-v1-0-0"]], "Troubleshooting installation issues": [[28, "troubleshooting-installation-issues"]], "Webhooks": [[28, "webhooks"]], "EKS": [[28, "eks"]], "Custom CNI": [[28, "custom-cni"]], "GKE": [[28, "gke"]], "Private clusters": [[28, "private-clusters"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/v1.11/sitemap.xml b/v1.11/sitemap.xml new file mode 100644 index 00000000000..b28dec8e6a5 --- /dev/null +++ b/v1.11/sitemap.xml @@ -0,0 +1,2 @@ + +https://operator.docs.scylladb.com/stable/contributing.htmlhttps://operator.docs.scylladb.com/stable/eks.htmlhttps://operator.docs.scylladb.com/stable/exposing.htmlhttps://operator.docs.scylladb.com/stable/generic.htmlhttps://operator.docs.scylladb.com/stable/gke.htmlhttps://operator.docs.scylladb.com/stable/multidc/eks.htmlhttps://operator.docs.scylladb.com/stable/helm.htmlhttps://operator.docs.scylladb.com/stable/index.htmlhttps://operator.docs.scylladb.com/stable/multidc/gke.htmlhttps://operator.docs.scylladb.com/stable/multidc/index.htmlhttps://operator.docs.scylladb.com/stable/manager.htmlhttps://operator.docs.scylladb.com/stable/multidc/multidc.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/automatic-cleanup.htmlhttps://operator.docs.scylladb.com/stable/migration.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/scylla-upgrade.htmlhttps://operator.docs.scylladb.com/stable/monitoring.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/index.htmlhttps://operator.docs.scylladb.com/stable/performance.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/maintenance-mode.htmlhttps://operator.docs.scylladb.com/stable/support/troubleshooting/installation.htmlhttps://operator.docs.scylladb.com/stable/releases.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/replace-node.htmlhttps://operator.docs.scylladb.com/stable/upgrade.htmlhttps://operator.docs.scylladb.com/stable/scylla-cluster-crd.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/restore.htmlhttps://operator.docs.scylladb.com/stable/support/index.htmlhttps://operator.docs.scylladb.com/stable/support/known-issues.htmlhttps://operator.docs.scylladb.com/stable/support/must-gather.htmlhttps://operator.docs.scylladb.com/stable/support/overview.htmlhttps://operator.docs.scylladb.com/stable/support/troubleshooting/index.htmlhttps://operator.docs.scylladb.com/stable/genindex.htmlhttps://operator.docs.scylladb.com/stable/404.htmlhttps://operator.docs.scylladb.com/stable/search.html \ No newline at end of file diff --git a/v1.11/support/index.html b/v1.11/support/index.html new file mode 100644 index 00000000000..5d341920d3b --- /dev/null +++ b/v1.11/support/index.html @@ -0,0 +1,575 @@ + + + + + + + + + + + + + Support | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Support

            + +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/support/known-issues.html b/v1.11/support/known-issues.html new file mode 100644 index 00000000000..674b2eb47c4 --- /dev/null +++ b/v1.11/support/known-issues.html @@ -0,0 +1,598 @@ + + + + + + + + + + + + + Known issues | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Known issues

            +
            +

            Scylla Manager does not boot up on Minikube

            +

            If your Scylla Manager is failing to apply 8th migration (008_*), then apply fix for TRUNCATE queries.

            +
            +
            +

            TRUNCATE queries does not work on Minikube

            +

            The TRUNCATE queries requires hairpinning to be enabled. On minikube this is disabled by default.

            +

            To fix it execute the following command:

            +
            minikube ssh sudo ip link set docker0 promisc on
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/support/must-gather.html b/v1.11/support/must-gather.html new file mode 100644 index 00000000000..e80899a8542 --- /dev/null +++ b/v1.11/support/must-gather.html @@ -0,0 +1,685 @@ + + + + + + + + + + + + + Gathering data with must-gather | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Gathering data with must-gather

            +

            must-gather is an embedded tool in Scylla Operator that helps collecting all the necessary info when something goes wrong.

            +

            The tool talks to the Kubernetes API, retrieves a predefined set of resources and saves them into a folder in your current directory. +By default, all collected Secrets are censored to avoid sending sensitive data. +That said, you can always review the archive before you attach it to an issue or your support request.

            +

            Given it needs to talk to the Kubernetes API, at the very least, you need to supply the --kubeconfig flag with a path to the kubeconfig file for your Kubernetes cluster, or set the KUBECONFIG environment variable.

            +
            +

            Running must-gather

            +

            There is more than one way to run must-gather. +Here are some examples of how you can run the tool.

            +
            +

            Prerequisites

            +

            All examples assume you have exported KUBECONFIG environment variable that points to a kubeconfig file on your machine. +If not, you can run this command to export the common default location. +Please make sure such a file exists.

            +
            export KUBECONFIG=~/.kube/config
            +ls -l "${KUBECONFIG}"
            +
            +
            +
            +

            Note

            +

            There can be slight deviations in the arguments for your container tool, depending on the container runtime, whether you use SELinux or similar factors.

            +

            As an example, the need for the Z option on volume mounts depends on whether you use SELinux and what context is applied on your file or directory. +If you get an error mentioning Error: lsetxattr <path>: operation not supported, try it without the Z option.

            +
            +

            Let’s also check whether your kubeconfig uses external authentication plugin. +You can determine that by running

            +
            kubectl config view --minify
            +
            +
            +

            and checking whether it uses an external exec plugin by looking for this pattern (containing the exec key)

            +
            users:
            +- name: <user_name>
            +  user:
            +    exec:
            +
            +
            +

            If not, you can skip the rest of this section.

            +

            In case your kubeconfig depends on external binaries, you have to take a few extra steps because the external binary won’t be available within our container to authenticate the requests.

            +

            Similarly to how Pods are run within Kubernetes, we’ll create a dedicated ServiceAccount for must-gather and use it to run the tool. +(When you are done using it, feel free to remove the Kubernetes resources created for that purpose.)

            +
            kubectl create namespace must-gather
            +kubectl -n must-gather create serviceaccount must-gather
            +kubectl create clusterrolebinding must-gather --clusterrole=cluster-admin --serviceaccount=must-gather:must-gather
            +export MUST_GATHER_TOKEN
            +MUST_GATHER_TOKEN=$( kubectl -n must-gather create token must-gather --duration=1h )
            +kubeconfig=$( mktemp )
            +# Create a copy of the existing kubeconfig and
            +# replace user authentication using yq, or by adjusting the fields manually.
            +kubectl config view --minify --raw -o yaml | yq -e '.users[0].user = {"token": env(MUST_GATHER_TOKEN)}' > "${kubeconfig}"
            +KUBECONFIG="${kubeconfig}"
            +
            +
            +
            +

            Note

            +

            If you don’t have yq installed, you can get it at https://github.com/mikefarah/yq/#install or you can replace the user authentication settings manually.

            +
            +
            +
            +

            Podman

            +
            podman run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro,Z" -v="$( pwd ):/workspace:Z" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig
            +
            +
            +
            +
            +

            Docker

            +
            docker run -it --pull=always --rm -v="${KUBECONFIG}:/kubeconfig:ro" -v="$( pwd ):/workspace" --workdir=/workspace docker.io/scylladb/scylla-operator:latest must-gather --kubeconfig=/kubeconfig
            +
            +
            +
            +
            +
            +

            Limiting must-gather to a particular namespace

            +

            If you are running a large Kubernetes cluster with many ScyllaClusters, it may be useful to limit the collection of ScyllaClusters to a particular namespace. +Unless you hit scale issues, we advise not to use this mode, as sometimes the ScyllaClusters affect other collected resources, like the manager or they form a multi-datacenter.

            +
            scylla-operator must-gather --namespace="<namespace_with_broken_scyllacluster>"
            +
            +
            +
            +

            Note

            +

            The --namespace flag affects only ScyllaClusters. +Other resources related to the operator installation or cluster state will still be collected from other namespaces.

            +
            +
            +

            Collecting every resource in the cluster

            +

            By default, must-gather collects only a predefined subset of resources. +You can also request collecting every resource in the Kubernetes API, if the default set wouldn’t be enough to debug an issue.

            +
            scylla-operator must-gather --all-resources
            +
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/support/overview.html b/v1.11/support/overview.html new file mode 100644 index 00000000000..38a7883cfa0 --- /dev/null +++ b/v1.11/support/overview.html @@ -0,0 +1,600 @@ + + + + + + + + + + + + + Support overview | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Support overview

            +
            +

            Get support

            +

            ScyllaDB provides administrators with paid support, including Scylla Operator.

            +
            +
            +

            Troubleshooting issues

            +

            To learn more about what to do when issues arise, visit our dedicated troubleshooting section.

            +
            +
            +

            Gather data about your cluster

            +

            Scylla Operator contains an embedded tool called must-gather that can collect the required information for requesting support or reporting issues. +Support requests and bug reports are required to attach the must-gather archive to help us understand the issue.

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/support/troubleshooting/index.html b/v1.11/support/troubleshooting/index.html new file mode 100644 index 00000000000..1265d2eb814 --- /dev/null +++ b/v1.11/support/troubleshooting/index.html @@ -0,0 +1,581 @@ + + + + + + + + + + + + + Troubleshooting | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Troubleshooting

            + +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/support/troubleshooting/installation.html b/v1.11/support/troubleshooting/installation.html new file mode 100644 index 00000000000..bf1686b9df3 --- /dev/null +++ b/v1.11/support/troubleshooting/installation.html @@ -0,0 +1,636 @@ + + + + + + + + + + + + + Troubleshooting installation issues | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Troubleshooting installation issues

            +
            +

            Webhooks

            +

            Scylla Operator provides several custom API resources that use webhooks to function properly.

            +

            Unfortunately, it is often the case that user’s clusters have modified SDN, that doesn’t extend to the control plane, and Kubernetes apiserver is not able to reach the pods that serve the webhook traffic. +Another common case are firewall rules that block the webhook traffic.

            +
            +

            Note

            +

            To be called a Kubernetes cluster, clusters are required to pass Kubernetes conformance test suite. +This suite includes tests that require Kubernetes apiserver to be able to reach webhook services.

            +
            +
            +

            Note

            +

            Before filing an issue, please make sure your cluster webhook traffic can reach your webhook services, independently of Scylla Operator resources.

            +
            +
            +

            EKS

            +
            +

            Custom CNI

            +

            EKS is currently breaking Kubernetes webhooks when used with custom CNI networking.

            +
            +

            Note

            +

            We advise you to avoid using such setups and use a conformant Kubernetes cluster that supports webhooks.

            +
            +

            There are some workarounds where you can reconfigure the webhook to use Ingress or hostNetwork instead, but it’s beyond a standard configuration that we support and not specific to the Scylla Operator.

            +
            +
            +
            +

            GKE

            +
            +

            Private clusters

            +

            If you use GKE private clusters you need to manually configure the firewall to allow webhook traffic. +You can find more information on how to do that in GKE private clusters docs.

            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.11/upgrade.html b/v1.11/upgrade.html new file mode 100644 index 00000000000..b666a2bc405 --- /dev/null +++ b/v1.11/upgrade.html @@ -0,0 +1,789 @@ + + + + + + + + + + + + + Upgrade of Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Upgrade of Scylla Operator

            +

            This page describes Scylla Operator upgrade procedures.
            +There are two generic update procedures - via Helm and via kubectl. Before upgrading, please check this page to find out +if your target version requires additional upgrade steps.

            +
            +

            Upgrade via Helm

            +

            Helm doesn’t support managing CustomResourceDefinition resources (#5871, #7735)
            +These are only created on first install and never updated. In order to update them, users have to do it manually.

            +

            Replace <release_name> with the name of your Helm release for Scylla Operator and replace <version> with the version number you want to install:

            +
              +
            1. Make sure Helm chart repository is up-to-date:

              +
              helm repo add scylla-operator https://storage.googleapis.com/scylla-operator-charts/stable
              +helm repo update
              +
              +
              +
            2. +
            3. Update CRD resources. We recommend using --server-side flag for kubectl apply, if your version supports it.

              +
              tmpdir=$( mktemp -d ) \
              +  && helm pull scylla-operator/scylla-operator --version <version> --untar --untardir "${tmpdir}" \
              +  && find "${tmpdir}"/scylla-operator/crds/ -name '*.yaml' -printf '-f=%p ' \
              +  | xargs kubectl apply
              +
              +
              +
            4. +
            5. Update Scylla Operator

              +
              helm upgrade --version <version> <release_name> scylla-operator/scylla-operator
              +
              +
              +
            6. +
            +
            +
            +

            Upgrade via kubectl

            +

            Replace <version> with the version number you want to install:

            +
              +
            1. Checkout source code of version you want to use:

              +
              git checkout <version>
              +
              +
              +
            2. +
            3. Manifests use rolling minor version tag, you may want to pin it to specific version:

              +
              find deploy/operator -name "*.yaml" | xargs sed --follow-symlinks -i -E "s^docker.io/scylladb/scylla-operator:[0-9]+\.[0-9]+^docker.io/scylladb/scylla-operator:<version>^g"
              +
              +
              +
            4. +
            5. Update Scylla Operator. We recommend using --server-side flag for kubectl apply, if your version supports it.

              +
              kubectl apply -f deploy/operator
              +
              +
              +
            6. +
            +
            +
            +
            +

            v1.2.0 -> v1.3.0

            +

            Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

            +
              +
            1. Checkout source code of v1.3.0:

              +
              git checkout v1.3.0
              +
              +
              +
            2. +
            3. Update Scylla Operator from deploy directory:

              +
              kubectl -n scylla-operator apply -f deploy/operator
              +
              +
              +
            4. +
            5. Wait until Scylla Operator is up and running:

              +
              kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
              +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
              +
              +
              +
            6. +
            +
            +
            +

            v1.1.0 -> v1.2.0

            +

            1.2.0 release brought a lot of changes to the Scylla Operator deployment process. +To properly update Scylla Operator one must delete old objects and install updated ones.

            +

            Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

            +
              +
            1. Checkout source code of v1.2.0:

              +
              git checkout v1.2.0
              +
              +
              +
            2. +
            3. Remove old scylla operator namespace - in our case it’s called scylla-operator-system:

              +
              kubectl delete namespace scylla-operator-system --wait=true
              +
              +
              +
            4. +
            5. Remove old webhooks:

              +
              kubectl delete MutatingWebhookConfiguration scylla-operator-mutating-webhook-configuration
              +kubectl delete ValidatingWebhookConfiguration scylla-operator-validating-webhook-configuration
              +
              +
              +
            6. +
            7. Install Scylla Operator from deploy directory:

              +
              kubectl -n scylla-operator apply -f deploy/operator
              +
              +
              +
            8. +
            9. Wait until Scylla Operator is up and running:

              +
              kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
              +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
              +
              +
              +
            10. +
            +
            +
            +

            v1.0.0 -> v1.1.0

            +

            During this update we will change probes and image for Scylla Operator. +A new version brings an automation for upgrade of sidecar image, so a rolling restart of managed Scylla clusters is expected.

            +
              +
            1. Get name of StatefulSet managing Scylla Operator

              +
              kubectl --namespace scylla-operator-system get sts --selector="control-plane=controller-manager"
              +
              +NAME                                 READY   AGE
              +scylla-operator-controller-manager   1/1     95m
              +
              +
              +
            2. +
            3. Change probes and used container image by applying following patch:

              +
              spec:
              +  template:
              +    spec:
              +      containers:
              +      - name: manager
              +        image: docker.io/scylladb/scylla-operator:1.1.0
              +        livenessProbe:
              +          httpGet:
              +            path: /healthz
              +            port: 8080
              +            scheme: HTTP
              +        readinessProbe:
              +          $retainKeys:
              +          - httpGet
              +          httpGet:
              +            path: /readyz
              +            port: 8080
              +            scheme: HTTP
              +
              +
              +

              To apply above patch save it to file (operator-patch.yaml for example) and apply to Operator StatefulSet:

              +
              kubectl -n scylla-operator-system patch sts scylla-operator-controller-manager --patch "$(cat operator-patch.yaml)"
              +
              +
              +
            4. +
            +
            +
            +

            v0.3.0 -> v1.0.0

            +

            Note: There’s an experimental migration procedure available here.

            +

            v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common +kind which is easier to disambiguate. (ScyllaCluster). +This change is backward incompatible, so Scylla cluster must be turned off and recreated from scratch. +In case you need to preserve your data, refer to backup and restore guide.

            +
              +
            1. Get list of existing Scylla clusters

              +
              kubectl -n scylla get cluster.scylla.scylladb.com
              +
              +NAME             AGE
              +simple-cluster   30m
              +
              +
              +
            2. +
            3. Delete each one of them

              +
              kubectl -n scylla delete cluster.scylla.scylladb.com simple-cluster
              +
              +
              +
            4. +
            5. Make sure you’re on v0.3.0 branch

              +
              git checkout v0.3.0
              +
              +
              +
            6. +
            7. Delete existing CRD and Operator

              +
              kubectl delete -f examples/generic/operator.yaml
              +
              +
              +
            8. +
            9. Checkout v1.0.0 version

              +
              git checkout v1.0.0
              +
              +
              +
            10. +
            11. Install new CRD and Scylla Operator

              +
              kubectl apply -f examples/common/operator.yaml
              +
              +
              +
            12. +
            13. Migrate your existing Scylla Cluster definition. Change apiVersion and kind from:

              +
              apiVersion: scylla.scylladb.com/v1alpha1
              +kind: Cluster
              +
              +
              +

              to:

              +
              apiVersion: scylla.scylladb.com/v1
              +kind: ScyllaCluster
              +
              +
              +
            14. +
            15. Once your cluster definition is ready, use kubectl apply to install fresh Scylla cluster.

            16. +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v1.9/.buildinfo b/v1.9/.buildinfo new file mode 100644 index 00000000000..9a1c4e15c4c --- /dev/null +++ b/v1.9/.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: 0b0406793c593d0da6785aa45028b5a9 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/v1.9/.doctrees/contributing.doctree b/v1.9/.doctrees/contributing.doctree new file mode 100644 index 00000000000..d36c81f1634 Binary files /dev/null and b/v1.9/.doctrees/contributing.doctree differ diff --git a/v1.9/.doctrees/eks.doctree b/v1.9/.doctrees/eks.doctree new file mode 100644 index 00000000000..183d219593f Binary files /dev/null and b/v1.9/.doctrees/eks.doctree differ diff --git a/v1.9/.doctrees/environment.pickle b/v1.9/.doctrees/environment.pickle new file mode 100644 index 00000000000..21d2431d1bc Binary files /dev/null and b/v1.9/.doctrees/environment.pickle differ diff --git a/v1.9/.doctrees/generic.doctree b/v1.9/.doctrees/generic.doctree new file mode 100644 index 00000000000..dfda546df4f Binary files /dev/null and b/v1.9/.doctrees/generic.doctree differ diff --git a/v1.9/.doctrees/gke.doctree b/v1.9/.doctrees/gke.doctree new file mode 100644 index 00000000000..88c42e9b762 Binary files /dev/null and b/v1.9/.doctrees/gke.doctree differ diff --git a/v1.9/.doctrees/helm.doctree b/v1.9/.doctrees/helm.doctree new file mode 100644 index 00000000000..3d8fc9a6661 Binary files /dev/null and b/v1.9/.doctrees/helm.doctree differ diff --git a/v1.9/.doctrees/index.doctree b/v1.9/.doctrees/index.doctree new file mode 100644 index 00000000000..5a1df8dcfb3 Binary files /dev/null and b/v1.9/.doctrees/index.doctree differ diff --git a/v1.9/.doctrees/known_issues.doctree b/v1.9/.doctrees/known_issues.doctree new file mode 100644 index 00000000000..41743e9a411 Binary files /dev/null and b/v1.9/.doctrees/known_issues.doctree differ diff --git a/v1.9/.doctrees/manager.doctree b/v1.9/.doctrees/manager.doctree new file mode 100644 index 00000000000..2fa780f8591 Binary files /dev/null and b/v1.9/.doctrees/manager.doctree differ diff --git a/v1.9/.doctrees/migration.doctree b/v1.9/.doctrees/migration.doctree new file mode 100644 index 00000000000..1704ed94ef0 Binary files /dev/null and b/v1.9/.doctrees/migration.doctree differ diff --git a/v1.9/.doctrees/monitoring.doctree b/v1.9/.doctrees/monitoring.doctree new file mode 100644 index 00000000000..81310411732 Binary files /dev/null and b/v1.9/.doctrees/monitoring.doctree differ diff --git a/v1.9/.doctrees/nodeoperations/automatic_cleanup.doctree b/v1.9/.doctrees/nodeoperations/automatic_cleanup.doctree new file mode 100644 index 00000000000..012c8430ffd Binary files /dev/null and b/v1.9/.doctrees/nodeoperations/automatic_cleanup.doctree differ diff --git a/v1.9/.doctrees/nodeoperations/index.doctree b/v1.9/.doctrees/nodeoperations/index.doctree new file mode 100644 index 00000000000..f6b24eebf2c Binary files /dev/null and b/v1.9/.doctrees/nodeoperations/index.doctree differ diff --git a/v1.9/.doctrees/nodeoperations/maintenance_mode.doctree b/v1.9/.doctrees/nodeoperations/maintenance_mode.doctree new file mode 100644 index 00000000000..d4e391871f3 Binary files /dev/null and b/v1.9/.doctrees/nodeoperations/maintenance_mode.doctree differ diff --git a/v1.9/.doctrees/nodeoperations/replace_node.doctree b/v1.9/.doctrees/nodeoperations/replace_node.doctree new file mode 100644 index 00000000000..02e6b5a0d74 Binary files /dev/null and b/v1.9/.doctrees/nodeoperations/replace_node.doctree differ diff --git a/v1.9/.doctrees/nodeoperations/restore.doctree b/v1.9/.doctrees/nodeoperations/restore.doctree new file mode 100644 index 00000000000..ace3e184b95 Binary files /dev/null and b/v1.9/.doctrees/nodeoperations/restore.doctree differ diff --git a/v1.9/.doctrees/nodeoperations/scylla_upgrade.doctree b/v1.9/.doctrees/nodeoperations/scylla_upgrade.doctree new file mode 100644 index 00000000000..c9cf0b4089e Binary files /dev/null and b/v1.9/.doctrees/nodeoperations/scylla_upgrade.doctree differ diff --git a/v1.9/.doctrees/performance.doctree b/v1.9/.doctrees/performance.doctree new file mode 100644 index 00000000000..8877ae9ab31 Binary files /dev/null and b/v1.9/.doctrees/performance.doctree differ diff --git a/v1.9/.doctrees/releases.doctree b/v1.9/.doctrees/releases.doctree new file mode 100644 index 00000000000..eac74037bb2 Binary files /dev/null and b/v1.9/.doctrees/releases.doctree differ diff --git a/v1.9/.doctrees/scylla_cluster_crd.doctree b/v1.9/.doctrees/scylla_cluster_crd.doctree new file mode 100644 index 00000000000..44519a40f62 Binary files /dev/null and b/v1.9/.doctrees/scylla_cluster_crd.doctree differ diff --git a/v1.9/.doctrees/upgrade.doctree b/v1.9/.doctrees/upgrade.doctree new file mode 100644 index 00000000000..845b200d141 Binary files /dev/null and b/v1.9/.doctrees/upgrade.doctree differ diff --git a/v1.9/.nojekyll b/v1.9/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/v1.9/404.html b/v1.9/404.html new file mode 100644 index 00000000000..067dc99ea74 --- /dev/null +++ b/v1.9/404.html @@ -0,0 +1,31 @@ + + + + + + + + + ScyllaDB + + + + + + + + + + + +
            +

            404

            +

            The ScyllaDB monster ate your page!

            +

            + Home +

            +
            + + + \ No newline at end of file diff --git a/v1.9/CNAME b/v1.9/CNAME new file mode 100644 index 00000000000..12aae904168 --- /dev/null +++ b/v1.9/CNAME @@ -0,0 +1 @@ +operator.docs.scylladb.com \ No newline at end of file diff --git a/v1.9/_images/logo.png b/v1.9/_images/logo.png new file mode 100644 index 00000000000..5bbfedad2ac Binary files /dev/null and b/v1.9/_images/logo.png differ diff --git a/v1.9/_sources/contributing.md.txt b/v1.9/_sources/contributing.md.txt new file mode 100644 index 00000000000..da5fc078732 --- /dev/null +++ b/v1.9/_sources/contributing.md.txt @@ -0,0 +1,155 @@ +# Contributing to Scylla Operator + +## Prerequisites + +To develop on scylla-operator, your environment must have the following: + +1. [Go 1.13](https://golang.org/dl/) + * Make sure [GOPATH](https://github.com/golang/go/wiki/SettingGOPATH) is set to `GOPATH=$HOME/go`. +2. [Kustomize v3.1.0](https://github.com/kubernetes-sigs/kustomize/releases/tag/v3.1.0) +3. [kubebuilder v2.3.1](https://github.com/kubernetes-sigs/kubebuilder/releases/tag/v2.3.1) +4. [Docker](https://docs.docker.com/install/) +5. Git client installed +6. Github account + +To install all dependencies (Go, kustomize, kubebuilder, dep), simply run: +```bash +./install-dependencies.sh +``` + +## Initial Setup + +### Create a Fork + +From your browser navigate to [http://github.com/scylladb/scylla-operator](http://github.com/scylladb/scylla-operator) and click the "Fork" button. + +### Clone Your Fork + +Open a console window and do the following: + +```bash +# Create the scylla operator repo path +mkdir -p $GOPATH/src/github.com/scylladb + +# Navigate to the local repo path and clone your fork +cd $GOPATH/src/github.com/scylladb + +# Clone your fork, where is your GitHub account name +git clone https://github.com//scylla-operator.git +``` + +### Add Upstream Remote + +First you will need to add the upstream remote to your local git: +```bash +# Add 'upstream' to the list of remotes +git remote add upstream https://github.com/scylladb/scylla-operator.git + +# Verify the remote was added +git remote -v +``` +Now you should have at least `origin` and `upstream` remotes. You can also add other remotes to collaborate with other contributors. + +## Development + +To add a feature or to make a bug fix, you will need to create a branch in your fork and then submit a pull request (PR) from the branch. + +### Building the project + +You can build the project using the Makefile commands: +* Open the Makefile and change the `IMG` environment variable to a repository you have access to. +* Run `make docker-push` and wait for the image to be built and uploaded in your repo. + +### Create a Branch + +From a console, create a new branch based on your fork and start working on it: + +```bash +# Ensure all your remotes are up to date with the latest +git fetch --all + +# Create a new branch that is based off upstream master. Give it a simple, but descriptive name. +# Generally it will be two to three words separated by dashes and without numbers. +git checkout -b feature-name upstream/master +``` + +Now you are ready to make the changes and commit to your branch. + +### Updating Your Fork + +During the development lifecycle, you will need to keep up-to-date with the latest upstream master. As others on the team push changes, you will need to `rebase` your commits on top of the latest. This avoids unnecessary merge commits and keeps the commit history clean. + +Whenever you need to update your local repository, you never want to merge. You **always** will rebase. Otherwise you will end up with merge commits in the git history. If you have any modified files, you will first have to stash them (`git stash save -u ""`). + +```bash +git fetch --all +git rebase upstream/master +``` + +Rebasing is a very powerful feature of Git. You need to understand how it works or else you will risk losing your work. Read about it in the [Git documentation](https://git-scm.com/docs/git-rebase), it will be well worth it. In a nutshell, rebasing does the following: +- "Unwinds" your local commits. Your local commits are removed temporarily from the history. +- The latest changes from upstream are added to the history +- Your local commits are re-applied one by one +- If there are merge conflicts, you will be prompted to fix them before continuing. Read the output closely. It will tell you how to complete the rebase. +- When done rebasing, you will see all of your commits in the history. + +## Submitting a Pull Request + +Once you have implemented the feature or bug fix in your branch, you will open a PR to the upstream repo. Before opening the PR ensure you have added unit tests, are passing the integration tests, cleaned your commit history, and have rebased on the latest upstream. + +In order to open a pull request (PR) it is required to be up to date with the latest changes upstream. If other commits are pushed upstream before your PR is merged, you will also need to rebase again before it will be merged. + +### Commit History + +To prepare your branch to open a PR, you will need to have the minimal number of logical commits so we can maintain +a clean commit history. Most commonly a PR will include a single commit where all changes are squashed, although +sometimes there will be multiple logical commits. + +```bash +# Inspect your commit history to determine if you need to squash commits +git log + +# Rebase the commits and edit, squash, or even reorder them as you determine will keep the history clean. +# In this example, the last 5 commits will be opened in the git rebase tool. +git rebase -i HEAD~5 +``` + +Once your commit history is clean, ensure you have based on the [latest upstream](#updating-your-fork) before you open the PR. + +### Commit messages + +Please make the first line of your commit message a summary of the change that a user (not a developer) of Operator would like to read, +and prefix it with the most relevant directory of the change followed by a colon. +The changelog gets made by looking at just these first lines so make it good! + +If you have more to say about the commit, then enter a blank line and carry on the description. +Remember to say why the change was needed - the commit itself shows what was changed. + +Writing more is better than less. Comparing the behaviour before the change to that after the change is very useful. +Imagine you are writing to yourself in 12 months time when you've forgotten everything about what you just did, and you need to get up to speed quickly. + +If the change fixes an issue then write Fixes #1234 in the commit message. +This can be on the subject line if it will fit. If you don't want to close the associated issue just put #1234 and the change will get linked into the issue. + +Here is an example of a short commit message: + +``` +sidecar: log on reconcile loop - fixes #1234 +``` + +And here is an example of a longer one: +``` + +api: now supports host networking (#1234) + +The operator CRD now has a "network" property that can be used to +select host networking as well as setting the apropriate DNS policy. + +Fixes #1234 +``` + +### Submitting + +Go to the [Scylla Operator github](https://www.github.com/scylladb/scylla-operator) to open the PR. If you have pushed recently, you should see an obvious link to open the PR. If you have not pushed recently, go to the Pull Request tab and select your fork and branch for the PR. + +After the PR is open, you can make changes simply by pushing new commits. Your PR will track the changes in your fork and update automatically. diff --git a/v1.9/_sources/eks.md.txt b/v1.9/_sources/eks.md.txt new file mode 100644 index 00000000000..b0024ba3227 --- /dev/null +++ b/v1.9/_sources/eks.md.txt @@ -0,0 +1,123 @@ +# Deploying Scylla on EKS + +This guide is focused on deploying Scylla on EKS with improved performance. +Performance tricks used by the script won't work with different machine tiers. +It sets up the kubelets on EKS nodes to run with [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and uses [local sdd disks](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ssd-instance-store.html) in RAID0 for maximum performance. + +Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the [general guide](generic.md). + +## TL;DR; + +If you don't want to run the commands step-by-step, you can just run a script that will set everything up for you: +```bash +# Edit according to your preference +EKS_REGION=us-east-1 +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c + +# From inside the examples/eks folder +cd examples/eks +./eks.sh -z "$EKS_ZONES" -r "$EKS_REGION" +``` + +After you deploy, see how you can [benchmark your cluster with cassandra-stress](#benchmark-with-cassandra-stress). + +## Walkthrough + +### EKS Setup + +#### Configure environment variables + +First of all, we export all the configuration options as environment variables. +Edit according to your own environment. + +``` +EKS_REGION=us-east-1 +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c +CLUSTER_NAME=scylla-demo +``` + +#### Creating an EKS cluster + +For this guide, we'll create an EKS cluster with the following: + +* A NodeGroup of 3 `i3-2xlarge` Nodes, where the Scylla Pods will be deployed. These nodes will only accept pods having `scylla-clusters` toleration. + +``` + - name: scylla-pool + instanceType: i3.2xlarge + desiredCapacity: 3 + labels: + pool: "scylla-pool" + taints: + role: "scylla-clusters:NoSchedule" + ssh: + allow: true + kubeletExtraConfig: + cpuManagerPolicy: static +``` + +* A NodeGroup of 4 `c4.2xlarge` Nodes to deploy `cassandra-stress` later on. These nodes will only accept pods having `cassandra-stress` toleration. + +``` + - name: cassandra-stress-pool + instanceType: c4.2xlarge + desiredCapacity: 4 + labels: + pool: "cassandra-stress-pool" + taints: + role: "cassandra-stress:NoSchedule" + ssh: + allow: true +``` + +* A NodeGroup of 1 `i3.large` Node, where the monitoring stack and operator will be deployed. +``` + - name: monitoring-pool + instanceType: i3.large + desiredCapacity: 1 + labels: + pool: "monitoring-pool" + ssh: + allow: true +``` + +### Installing Required Tools + +#### Installing script third party dependencies + +Script requires several dependencies: +- Helm - See: https://docs.helm.sh/using_helm/#installing-helm +- eksctl - See: https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html +- kubectl - See: https://kubernetes.io/docs/tasks/tools/install-kubectl/ + + +#### Install the local provisioner + +We deploy the local volume provisioner, which will discover their mount points and make them available as PersistentVolumes. +``` +helm install local-provisioner examples/common/provisioner +``` + +#### Deploy tuning DaemonSet + +Deploy tuning DaemonSet, this will configure your disks and apply several optimizations +``` +kubectl apply -f node-setup-daemonset.yaml +``` + +### Installing the Scylla Operator and Scylla + +Now you can follow the [generic guide](generic.md) to launch your Scylla cluster in a highly performant environment. + +#### Accessing the database + +Instructions on how to access the database can also be found in the [generic guide](generic.md). + +### Deleting an EKS cluster + +Once you are done with your experiments delete your cluster using the following command: + +``` +eksctl delete cluster "${CLUSTER_NAME}" +``` diff --git a/v1.9/_sources/generic.md.txt b/v1.9/_sources/generic.md.txt new file mode 100644 index 00000000000..ef78f8501fc --- /dev/null +++ b/v1.9/_sources/generic.md.txt @@ -0,0 +1,375 @@ +# Deploying Scylla on a Kubernetes Cluster + +This is a guide to deploy a Scylla Cluster in a generic Kubernetes environment, meaning that Scylla will not be deployed with the ideal performance. +Scylla performs the best when it has fast disks and direct access to the cpu. +This requires some extra setup, which is platform-specific. +For specific configuration and setup, check for details about your particular environment: + +* [GKE](gke.md) + +## Prerequisites + +* A Kubernetes cluster +* A [Storage Class](https://kubernetes.io/docs/concepts/storage/storage-classes/) to provision [PersistentVolumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/). +* Helm 3 installed, Go to the [helm docs](https://docs.helm.sh/using_helm/#installing-helm) if you need to install it. + Make sure that you enable the [stable repository](https://github.com/helm/charts#how-do-i-enable-the-stable-repository-for-helm-3) + +## Running locally + +Running kubernetes locally is a daunting and error prone task. +Fortunately there are ways to make life easier and [Minikube](https://minikube.sigs.k8s.io/docs/) makes it a breeze. + +We need to give minikube a little bit more resources than default so start minikube like this: +```console +minikube start --cpus=6 +``` + +Then make kubectl aware of this local installation like this: +```console +eval $(minikube docker-env) +``` + +## Download Scylla Operator +In this guide you will be using the examples and manifests from [Scylla Operator repository](https://github.com/scylladb/scylla-operator), so start off by cloning it to your local machine. +```console +git clone git@github.com:scylladb/scylla-operator.git +cd scylla-operator +``` + +## Deploy Cert Manager +First deploy Cert Manager, you can either follow [upsteam instructions](https://cert-manager.io/docs/installation/kubernetes/) or use following command: + +```console +kubectl apply -f examples/common/cert-manager.yaml +``` +This will install Cert Manager to provision a self-signed certificate. + +Once it's deployed, wait until Cert Manager is ready: + +```console +kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io +kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook +``` + +## Deploy Scylla Operator + +Deploy the Scylla Operator using the following commands: + +```console +kubectl apply -f examples/common/operator.yaml +``` + +This will install the operator in namespace `scylla-operator`. +Wait until it's ready: + +```console +kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator +``` + +If you want to check the logs of the operator you can do so with: + + ```console +kubectl -n scylla-operator logs deployment.apps/scylla-operator +``` + +## Create and Initialize a Scylla Cluster + +Now that the operator is running, we can create an instance of a Scylla cluster by creating an instance of the `clusters.scylla.scylladb.com` resource. +Some of that resource's values are configurable, so feel free to browse `cluster.yaml` and tweak the settings to your liking. +Full details for all the configuration options can be found in the [Scylla Cluster CRD documentation](scylla_cluster_crd.md). + +When you are ready to create a Scylla cluster, simply run: + +```console +kubectl create -f examples/generic/cluster.yaml +``` + +We can verify that a Kubernetes object has been created that represents our new Scylla cluster with the command below. +This is important because it shows that has successfully extended Kubernetes to make Scylla clusters a first class citizen in the Kubernetes cloud-native environment. + +```console +kubectl -n scylla get ScyllaCluster +``` + +Checking the pods that are created is as easy as: + +```console +kubectl -n scylla get pods +``` + +The output should be something like: + +```console +NAME READY STATUS RESTARTS AGE +simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 9m49s +simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 7m43s +simple-cluster-us-east-1-us-east-1a-2 2/2 Running 0 6m46s +``` + +It is important to note that the operator creates these instances according to a pattern. +This pattern is as follows: `CLUSTER_NAME-DATACENTER_NAME-RACK_NAME-INSTANCE_NUMBER` as specified in `cluster.yaml`. + +In the above example we have the following properties: + + - CLUSTER_NAME: `simple-cluster` + - DATACENTER_NAME: `us-east-1` + - RACK_NAME: `us-east-1a` + - INSTANCE_NUMBER: An automatically generated number attached to the pod name. + +We picked the names to resemble something you can find in a cloud service but this is inconsequential, they can be set to anything you want. + +To check if all the desired members are running, you should see the same number of entries from the following command as the number of members that was specified in `cluster.yaml`: + +```console +kubectl -n scylla get pod -l app=scylla +``` + +You can also track the state of a Scylla cluster from its status. To check the current status of a Cluster, run: + +```console +kubectl -n scylla describe ScyllaCluster simple-cluster +``` + +Checking the logs of the running scylla instances can be done like this: + +```console +kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 scylla +``` + +### Configure host networking + +To squeeze the most out of your deployment it is sometimes necessary to employ [host networking](https://kubernetes.io/docs/concepts/services-networking/). +To enable this the CRD allows for specifying a `network` parameter as such: + +```yaml +version: 4.0.0 + agentVersion: 2.0.2 + cpuset: true + network: + hostNetworking: true +``` + +This will result in hosts network to be used for the Scylla Stateful Set deployment. + +### Configure container kernel parameters + +Sometimes it is necessary to run the container with different kernel parameters. +In order to support this, the Scylla Operator defines a cluster property `sysctls` that is a list of the desired key-value pairs to set. + +___For example___: To increase the number events available for asynchronous IO processing in the Linux kernel to N set sysctls to`fs.aio-max-nr=N`. + +```yaml +spec: + sysctls: + - "fs.aio-max-nr=2097152" +``` + +### Deploying Alternator + +The operator is also capable of deploying [Alternator](https://www.scylladb.com/alternator/) instead of the regular Scylla. +This requires a small change in the cluster definition. +Change the `cluster.yaml` file from this: +```yaml +spec: + version: 4.0.0 + agentVersion: 2.0.2 + developerMode: true + datacenter: + name: us-east-1 +``` +to this: +```yaml +spec: + version: 4.0.0 + alternator: + port: 8000 + writeIsolation: only_rmw_uses_lwt + agentVersion: 2.0.2 + developerMode: true + datacenter: + name: us-east-1 +``` +You can specify whichever port you want. + +You must provide desired write isolation, supported values are: "always", "forbid_rmw", "only_rmw_uses_lwt". +Difference between those isolation levels can be found in Scylla Alternator documentation. + +Once this is done the regular CQL ports will no longer be available, the cluster is a pure Alienator cluster. + +## Accessing the Database + +* From kubectl: + +To get a cqlsh shell in your new Cluster: +```console +kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- cqlsh +> DESCRIBE KEYSPACES; +``` + + +* From inside a Pod: + +When you create a new Cluster, automatically creates a Service for the clients to use in order to access the Cluster. +The service's name follows the convention `-client`. +You can see this Service in your cluster by running: +```console +kubectl -n scylla describe service simple-cluster-client +``` +Pods running inside the Kubernetes cluster can use this Service to connect to Scylla. +Here's an example using the [Python Driver](https://github.com/datastax/python-driver): +```python +from cassandra.cluster import Cluster + +cluster = Cluster(['simple-cluster-client.scylla.svc']) +session = cluster.connect() +``` + +If you are running the Alternator you can access the API on the port you specified using plain http. + +## Configure Scylla + +The operator can take a ConfigMap and apply it to the scylla.yaml configuration file. +This is done by adding a ConfigMap to Kubernetes and refering to this in the Rack specification. +The ConfigMap is just a file called `scylla.yaml` that has the properties you want to change in it. +The operator will take the default properties for the rest of the configuration. + +* Create a ConfigMap the default name that the operator uses is `scylla-config`: +```console +kubectl create configmap scylla-config -n scylla --from-file=/path/to/scylla.yaml +``` +* Wait for the mount to propagate and then restart the cluster: +```console +kubectl rollout restart -n scylla statefulset/simple-cluster-us-east-1-us-east-1a +``` +* The new config should be applied automatically by the operator, check the logs to be sure. + +Configuring `cassandra-rackdc.properties` is done by adding the file to the same mount as `scylla.yaml`. +```console +kubectl create configmap scylla-config -n scylla --from-file=/tmp/scylla.yaml --from-file=/tmp/cassandra-rackdc.properties -o yaml --dry-run | kubectl replace -f - +``` +The operator will then apply the overridable properties `prefer_local` and `dc_suffix` if they are available in the provided mounted file. + +## Configure Scylla Manager Agent + +The operator creates a second container for each scylla instance that runs [Scylla Manager Agent](https://hub.docker.com/r/scylladb/scylla-manager-agent). +This container serves as a sidecar and it's the main endpoint for interacting with Scylla API. +The Scylla Manager Agent can be configured with various things such as the security token used to allow access to Scylla API and storage providers for backups. + +To configure the agent you just create a new secret called _scylla-agent-config-secret_ and populate it with the contents in the `scylla-manager-agent.yaml` file like this: +```console +kubectl create secret -n scylla generic scylla-agent-config-secret --from-file scylla-manager-agent.yaml +``` + +See [Scylla Manager Agent configuration](https://docs.scylladb.com/operating-scylla/manager/2.0/agent-configuration-file/) for a complete reference of the Scylla Manager agent config file. + +### Scylla Manager Agent auth token + +Operator provisions Agent auth token by copying value from user provided config secret or auto generates it if it's empty. +To check which value is being used, decode content of `-auth-token` secret. +To change it simply remove the secret. Operator will create a new one. To pick up the change in the cluster, initiate a rolling restart. + +## Set up monitoring + +To set up monitoring using Prometheus and Grafana follow [this guide](monitoring.md). + +## Scale Up + +The operator supports scale up of a rack as well as addition of new racks. To make the changes, you can use: +```console +kubectl -n scylla edit ScyllaCluster simple-cluster +``` +* To scale up a rack, change the `Spec.Members` field of the rack to the desired value. +* To add a new rack, append the `racks` list with a new rack. Remember to choose a different rack name for the new rack. +* After editing and saving the yaml, check your cluster's Status and Events for information on what's happening: +```console +kubectl -n scylla describe ScyllaCluster simple-cluster +``` + +## Benchmark with cassandra-stress + +After deploying our cluster along with the monitoring, we can benchmark it using cassandra-stress and see its performance in Grafana. We have a mini cli that generates Kubernetes Jobs that run cassandra-stress against a cluster. + +> Because cassandra-stress doesn't scale well to multiple cores, we use multiple jobs with a small core count for each + +```bash + +# Run a benchmark with 10 jobs, with 6 cpus and 50.000.000 operations each. +# Each Job will throttle throughput to 30.000 ops/sec for a total of 300.000 ops/sec. +hack/cass-stress-gen.py --num-jobs=10 --cpu=6 --memory=20G --ops=50000000 --limit=30000 +kubectl apply -f scripts/cassandra-stress.yaml +``` + +Make sure you set the proper arguments in case you have altered things such as _name_ or _namespace_. + +```bash +./hack/cass-stress-gen.py -h +usage: cass-stress-gen.py [-h] [--num-jobs NUM_JOBS] [--name NAME] [--namespace NAMESPACE] [--scylla-version SCYLLA_VERSION] [--host HOST] [--cpu CPU] [--memory MEMORY] [--ops OPS] [--threads THREADS] [--limit LIMIT] + [--connections-per-host CONNECTIONS_PER_HOST] [--print-to-stdout] [--nodeselector NODESELECTOR] + +Generate cassandra-stress job templates for Kubernetes. + +optional arguments: + -h, --help show this help message and exit + --num-jobs NUM_JOBS number of Kubernetes jobs to generate - defaults to 1 + --name NAME name of the generated yaml file - defaults to cassandra-stress + --namespace NAMESPACE + namespace of the cassandra-stress jobs - defaults to "default" + --scylla-version SCYLLA_VERSION + version of scylla server to use for cassandra-stress - defaults to 4.0.0 + --host HOST ip or dns name of host to connect to - defaults to scylla-cluster-client.scylla.svc + --cpu CPU number of cpus that will be used for each job - defaults to 1 + --memory MEMORY memory that will be used for each job in GB, ie 2G - defaults to 2G * cpu + --ops OPS number of operations for each job - defaults to 10000000 + --threads THREADS number of threads used for each job - defaults to 50 * cpu + --limit LIMIT rate limit for each job - defaults to no rate-limiting + --connections-per-host CONNECTIONS_PER_HOST + number of connections per host - defaults to number of cpus + --print-to-stdout print to stdout instead of writing to a file + --nodeselector NODESELECTOR + nodeselector limits cassandra-stress pods to certain nodes. Use as a label selector, eg. --nodeselector role=scylla +``` +While the benchmark is running, open up Grafana and take a look at the monitoring metrics. + +After the Jobs finish, clean them up with: +```bash +kubectl delete -f scripts/cassandra-stress.yaml +``` + +## Scale Down + +The operator supports scale down of a rack. To make the changes, you can use: +```console +kubectl -n scylla edit ScyllaCluster simple-cluster +``` +* To scale down a rack, change the `Spec.Members` field of the rack to the desired value. +* After editing and saving the yaml, check your cluster's Status and Events for information on what's happening: +```console +kubectl -n scylla describe ScyllaCluster simple-cluster +``` + +## Clean Up + +To clean up all resources associated with this walk-through, you can run the commands below. + +**NOTE:** this will destroy your database and delete all of its associated data. + +```console +kubectl delete -f examples/generic/cluster.yaml +kubectl delete -f examples/common/operator.yaml +kubectl delete -f examples/common/cert-manager.yaml +``` + +## Troubleshooting + +If the cluster does not come up, the first step would be to examine the operator's logs: + +```console +kubectl -n scylla-operator logs deployment.apps/scylla-operator +``` + +If everything looks OK in the operator logs, you can also look in the logs for one of the Scylla instances: + +```console +kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 +``` diff --git a/v1.9/_sources/gke.md.txt b/v1.9/_sources/gke.md.txt new file mode 100644 index 00000000000..7e5a290f657 --- /dev/null +++ b/v1.9/_sources/gke.md.txt @@ -0,0 +1,170 @@ +# Deploying Scylla on GKE + +This guide is focused on deploying Scylla on GKE with maximum performance (without any persistence guarantees). +It sets up the kubelets on GKE nodes to run with [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and uses [local sdd disks](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/local-ssd) in RAID0 for maximum performance. + +Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the [general guide](generic.md). + +## TL;DR; + +If you don't want to run the commands step-by-step, you can just run a script that will set everything up for you: +```bash +# Edit according to your preference +GCP_USER=$(gcloud config list account --format "value(core.account)") +GCP_PROJECT=$(gcloud config list project --format "value(core.project)") +GCP_ZONE=us-west1-b + +# From inside the examples/gke folder +cd examples/gke +./gke.sh -u "$GCP_USER" -p "$GCP_PROJECT" -z "$GCP_ZONE" + +# Example: +# ./gke.sh -u yanniszark@arrikto.com -p gke-demo-226716 -z us-west1-b +``` + +:warning: Make sure to pass a ZONE (ex.: us-west1-b) and not a REGION (ex.: us-west1) or it will deploy nodes in each ZONE available in the region. + +After you deploy, see how you can [benchmark your cluster with cassandra-stress](#benchmark-with-cassandra-stress). + +## Walkthrough + +### Google Kubernetes Engine Setup + +#### Configure environment variables + +First of all, we export all the configuration options as environment variables. +Edit according to your own environment. + +``` +GCP_USER=$( gcloud config list account --format "value(core.account)" ) +GCP_PROJECT=$( gcloud config list project --format "value(core.project)" ) +GCP_REGION=us-west1 +GCP_ZONE=us-west1-b +CLUSTER_NAME=scylla-demo +CLUSTER_VERSION=$( gcloud container get-server-config --zone ${GCP_ZONE} --format "value(validMasterVersions[0])" ) +``` + +#### Creating a GKE cluster + +First we need to change kubelet CPU Manager policy to static by providing a config file. Create file called `systemconfig.yaml` with the following content: +``` +kubeletConfig: + cpuManagerPolicy: static +``` + +Then we'll create a GKE cluster with the following: + +1. A NodePool of 2 `n1-standard-8` Nodes, where the operator and the monitoring stack will be deployed. These are generic Nodes and their free capacity can be used for other purposes. + ``` + gcloud container \ + clusters create "${CLUSTER_NAME}" \ + --cluster-version "${CLUSTER_VERSION}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-8" \ + --num-nodes "2" \ + --disk-type "pd-ssd" --disk-size "20" \ + --image-type "UBUNTU_CONTAINERD" \ + --system-config-from-file=systemconfig.yaml \ + --enable-stackdriver-kubernetes \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +2. A NodePool of 2 `n1-standard-32` Nodes to deploy `cassandra-stress` later on. + + ``` + gcloud container --project "${GCP_PROJECT}" \ + node-pools create "cassandra-stress-pool" \ + --cluster "${CLUSTER_NAME}" \ + --zone "${GCP_ZONE}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-32" \ + --num-nodes "2" \ + --disk-type "pd-ssd" --disk-size "20" \ + --node-taints role=cassandra-stress:NoSchedule \ + --image-type "UBUNTU_CONTAINERD" \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +3. A NodePool of 4 `n1-standard-32` Nodes, where the Scylla Pods will be deployed. Each of these Nodes has 8 local SSDs attached, which are combined into a RAID0 array by using gcloud beta feature `ephemeral-storage`. It is important to disable `autoupgrade` and `autorepair`. Automatic cluster upgrade or node repair has a hard timeout after which it no longer respect PDBs and force deletes the Compute Engine instances, which also deletes all data on the local SSDs. At this point, it's better to handle upgrades manually, with more control over the process and error handling. + ``` + gcloud beta container \ + node-pools create "scylla-pool" \ + --cluster "${CLUSTER_NAME}" \ + --node-version "${CLUSTER_VERSION}" \ + --machine-type "n1-standard-32" \ + --num-nodes "4" \ + --disk-type "pd-ssd" --disk-size "20" \ + --ephemeral-storage local-ssd-count="8" \ + --node-taints role=scylla-clusters:NoSchedule \ + --node-labels scylla.scylladb.com/gke-ephemeral-storage-local-ssd=true \ + --image-type "UBUNTU_CONTAINERD" \ + --no-enable-autoupgrade \ + --no-enable-autorepair + ``` + +#### Setting Yourself as `cluster-admin` +> (By default GKE doesn't give you the necessary RBAC permissions) + +Get the credentials for your new cluster +``` +gcloud container clusters get-credentials "${CLUSTER_NAME}" --zone="${GCP_ZONE}" +``` + +Create a ClusterRoleBinding for your user. +In order for this to work you need to have at least permission `container.clusterRoleBindings.create`. +The easiest way to obtain this permission is to enable the `Kubernetes Engine Admin` role for your user in the GCP IAM web interface. +``` +kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user "${GCP_USER}" +``` + + +### Installing Required Tools + +#### Installing Helm + +If you don't have Helm installed, Go to the [helm docs](https://docs.helm.sh/using_helm/#installing-helm) to get the binary for your distro. + +#### Install xfs-formatter DaemonSet + +To run Scylla, it is necessary to convert ephemeral storage's filesystem to `xfs`. Deploy the `xfs-formatter` DaemonSet to have it taken care of. +Unfortunately, GKE is only able to provision the ephemeral storage with `ext4` filesystem while Scylla requires `xfs` filesystem. Deploying the `xfs-format` DaemonSet will format the storage as `xfs` and prevent GKE from reformatting it back to `ext4`. + +Note that despite our best efforts, this solution is only a workaround. Its robustness depends on GKE's disk formatting logic remaining unchanged, for which there is no guarantee. +``` +kubectl apply -f examples/gke/xfs-formatter-daemonset.yaml +``` + +#### Install the local provisioner + +Afterwards, deploy the local volume provisioner, which will discover the RAID0 arrays' mount points and make them available as PersistentVolumes. +``` +helm install local-provisioner examples/common/provisioner +``` + +### Deploy Scylla cluster +In order for the example to work you need to modify the cluster definition in the following way: + +``` +sed -i "s//${GCP_REGION}/g;s//${GCP_ZONE}/g" examples/gke/cluster.yaml +``` + +This will inject your region and zone into the cluster definition so that it matches the kubernetes cluster you just created. + +### Installing the Scylla Operator and Scylla + +Now you can follow the [generic guide](generic.md) to install the operator and launch your Scylla cluster in a highly performant environment. + +#### Accessing the database + +Instructions on how to access the database can also be found in the [generic guide](generic.md). + +### Deleting a GKE cluster + +Once you are done with your experiments delete your cluster using the following command: + +``` +gcloud container --project "${GCP_PROJECT}" clusters delete --zone "${GCP_ZONE}" "${CLUSTER_NAME}" +``` diff --git a/v1.9/_sources/helm.md.txt b/v1.9/_sources/helm.md.txt new file mode 100644 index 00000000000..c226ee8c13c --- /dev/null +++ b/v1.9/_sources/helm.md.txt @@ -0,0 +1,339 @@ +# Deploying Scylla stack using Helm Charts + +In this example we will install Scylla stack on Kubernetes. This includes the following components: +- Scylla Operator +- Scylla Manager +- Scylla + +We will use Minikube K8s cluster, but this could be any K8s cluster supported by the Scylla Operator. + +### Prerequisites + +- Kubernetes 1.16+ +- Helm 3+ + +### TL;DR + +``` +helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable +helm repo update +kubectl apply -f examples/common/cert-manager.yaml +helm install scylla-operator scylla/scylla-operator --create-namespace --namespace scylla-operator +helm install scylla-manager scylla/scylla-manager --create-namespace --namespace scylla-manager +helm install scylla scylla/scylla --create-namespace --namespace scylla +``` + +### Deploy Cert Manager + +This step is optional if you want to use your own certificate. +If you don't have one, make sure to not disable autogeneration using Scylla Operator Helm Chart. + +First deploy Cert Manager, you can either follow [upsteam instructions](https://cert-manager.io/docs/installation/kubernetes/) or use following command: + +```console +kubectl apply -f examples/common/cert-manager.yaml +``` + +Once it's deployed, wait until all Cert Manager pods will enter into Running state: + +```console +kubectl wait -n cert-manager --for=condition=ready pod -l app=cert-manager --timeout=60s +``` + +### Helm Chart repository + +To install Scylla Helm Chart repository execute the following commands: +``` +helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable +helm repo update +``` + +Then you can search through repository, it should contain at least three Helm charts: +``` +helm search repo scylla +NAME CHART VERSION APP VERSION DESCRIPTION +scylla/scylla 1.0.1 v1.0.1 Scylla is a close-to-the-hardware rewrite of Ca... +scylla/scylla-manager 1.0.1 v1.0.1 Scylla Manager automates database operations. +scylla/scylla-operator 1.0.1 v1.0.1 Scylla Operator is a Kubernetes Operator for ma... +``` + +All these charts should be installable without any need of customizing (defaults are provided). +Although Helm is used for this particular reason, so lets customize them a bit. + +### Scylla Operator Chart + +This chart is very simple, most interesting customizable fields are `image`, `resources` and `webhook`. +All others can be looked up in Chart source in Scylla Operator repository. + +#### image + +Image allows to define which Scylla Operator image will be used. By default it downloads the image from main +Docker Hub repository, using version defined in Helm Chart. +You can also change `pullPolicy` if default one does not +fullfill your needs. In [Kubernetes documentation](https://kubernetes.io/docs/concepts/containers/images/) you +can read more about different pull policies. + +Image URL will be composed based on these fields in follwing pattern: +`repository/scylla-operator:tag` +```yaml +image: + repository: scylladb + pullPolicy: IfNotPresent + tag: "" +``` + +#### resources + +You can customize how much resources will be allocated for Operator pods via `resource` field: +```yaml +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 32Mi +``` + +To read more about resource specification, follow [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +#### webhook + +Webhook field allows to decide whether you want to use autogenerated self-signed certificate using Cert Manager or +whether you want to provide your own certificate. + +`createSelfSignedCertificate` specifies whether a self-signed certificate should be created using Cert Manager +`certificateSecretName`: name of a secret containing custom certificate. + +```yaml +webhook: + createSelfSignedCertificate: true + certificateSecretName: "" +``` + +#### Customization + +You can customize all these fields and others by providing file containing desired values. +Content of this file will overwrite default values. + +You can find an example in Scylla Operator repository under `examples/helm/values.operator.yaml` + +#### Installation + +To deploy Scylla Operator using customized values file execute the following: +``` +helm install scylla-operator scylla/scylla-operator --values examples/helm/values.operator.yaml --create-namespace --namespace scylla-operator +``` + +### Scylla Helm Chart + +Scylla Chart allows to customize and deploy Scylla cluster. +By default Scylla Helm charts deploys working Scylla cluster, but of course we can customize it. + +#### Customization + +Versions of images used in the cluster can be set via `scyllaImage` and `agentImage` +```yaml +scyllaImage: + repository: scylladb/scylla + tag: 4.3.0 + +agentImage: + repository: scylladb/scylla-manager-agent + tag: 2.2.1 +``` + +A minimal Scylla cluster can be expressed as: +```yaml +datacenter: us-east-1 +racks: +- name: us-east-1b + members: 2 + storage: + capacity: 5G + resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 1 + memory: 1Gi +``` + +Above cluster will use 4.3.0 Scylla, 2.2.1 Scylla Manager Agent sidecar and will have a single rack having 2 nodes. +Each node will have a single CPU and 1 GiB of memory. + +For other customizable fields, please refer to [ScyllaCluster CRD definition](scylla_cluster_crd.md). +CRD Rack Spec and Helm Chart Rack should have the same fields. + +#### Installation + +To deploy Scylla cluster using customzied values file execute the following command: +``` +helm install scylla scylla/scylla --values examples/helm/values.cluster.yaml --create-namespace --namespace scylla +``` + +Scylla Operator will provision this cluster on your K8s environment. + +### Scylla Manager Helm Chart + +Scylla Manager Chart allows to customize and deploy Scylla Manager in K8s environment. +Scylla Manager consist of two applications (Scylla Manager itself and Scylla Manager Controller) and additional Scylla cluster. + +To read more about Scylla Manager see [Manager guide](manager.md). + +#### Scylla Manager + +To set version of used Scylla Manager you can use `image` field: +```yaml +image: + repository: scylladb + pullPolicy: IfNotPresent + tag: 2.2.1 +``` +To control how many resources are allocated for Scylla Manager use `resource` field: +```yaml +resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 500m + memory: 500Mi +``` + +#### Scylla Manager Controller + +Similarly Scylla Manager Controller image can be customized: + +```yaml +controllerImage: + repository: scylladb + pullPolicy: IfNotPresent + tag: "" +``` + +And allocated resources: +```yaml +controllerResources: + limits: + cpu: 100m + memory: 30Mi + requests: + cpu: 100m + memory: 20Mi +``` + +#### Scylla + +To customize internal Scylla instance dedicated to Scylla Manager, see guide above customizing Scylla Helm Chart. +It's definition should land as a `scylla` field. + +#### Customization + +All others customizable fields can be looked up in Chart source in Scylla Operator repository. + +#### Installation + +To deploy Scylla Manager using customized values file execute the following command: +``` +helm install scylla-manager scylla/scylla-manager --values examples/helm/values.manager.yaml --create-namespace --namespace scylla-manager +``` + +## Results + +Scylla need some time to bootstrap all nodes, but after some time you should be ready to roll. It was simple isn't it? +You can validate if everything was set up correctly by looking at the all resources created in used namespaces. + +Scylla Operator: +```shell +$ kubectl -n scylla-operator get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-operator-5dbcb54f5c-vjm4m 1/1 Running 0 51s +pod/scylla-operator-5dbcb54f5c-wfjbw 1/1 Running 0 51s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-operator-webhook ClusterIP 10.105.207.130 443/TCP 51s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/scylla-operator 2/2 2 2 51s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/scylla-operator-5dbcb54f5c 2 2 2 51s + +``` + +Operator is running! + +Scylla Manager: +```shell +$ kubectl -n scylla-manager get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-manager-669db64dd-bcm4v 1/1 Running 0 89s +pod/scylla-manager-controller-844ccc56c4-drbth 1/1 Running 0 89s +pod/scylla-manager-controller-844ccc56c4-rhwqx 1/1 Running 0 89s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-manager ClusterIP 10.105.231.53 80/TCP,5090/TCP 89s +service/scylla-manager-client ClusterIP None 9180/TCP,5090/TCP 89s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/scylla-manager 1/1 1 1 89s +deployment.apps/scylla-manager-controller 2/2 2 2 89s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/scylla-manager-669db64dd 1 1 1 89s +replicaset.apps/scylla-manager-controller-844ccc56c4 2 2 2 89s + + +``` + +Good to go, ready to serve! + +Scylla itself: +```shell +$ kubectl -n scylla get all + +NAME READY STATUS RESTARTS AGE +pod/scylla-us-east-1-us-east-1b-0 2/2 Running 0 5m58s +pod/scylla-us-east-1-us-east-1b-1 2/2 Running 0 4m29s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/scylla-client ClusterIP None 9180/TCP,5090/TCP 5m59s +service/scylla-us-east-1-us-east-1b-0 ClusterIP 10.43.149.92 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 5m58s +service/scylla-us-east-1-us-east-1b-1 ClusterIP 10.43.49.0 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 4m29s + +NAME READY AGE +statefulset.apps/scylla-us-east-1-us-east-1b 2/2 5m59s +``` + +Two running nodes, exactly what we were asking for. + +## Monitoring + +To spin up a Prometheus monitoring refer to [monitoring guide](monitoring.md). + +Helm charts can create ServiceMonitors needed to observe Scylla Managger and Scylla. +Both of these Helm Charts allows to specify whether you want to create a ServiceMonitor: +```yaml +serviceMonitor: + create: false +``` + +Change `create` to `true` and update your current deployment using: +```shell +helm upgrade --install scylla --namespace scylla scylla/scylla -f examples/helm/values.cluster.yaml +``` + +Helm should notice the difference, install the ServiceMonitor, and then Prometheous will be able to scrape metrics. + +## Cleanup + +To remove these applications you can simply uninstall them using Helm CLI: +```shell +helm uninstall scylla -n scylla +helm uninstall scylla-manager -n scylla-manager +helm uninstall scylla-operator -n scylla-operator +``` diff --git a/v1.9/_sources/index.rst.txt b/v1.9/_sources/index.rst.txt new file mode 100644 index 00000000000..2746d10038c --- /dev/null +++ b/v1.9/_sources/index.rst.txt @@ -0,0 +1,62 @@ +============================= +Scylla Operator Documentation +============================= + +.. toctree:: + :hidden: + :maxdepth: 1 + + generic + eks + gke + helm + manager + monitoring + migration + nodeoperations/index + performance + upgrade + releases + known_issues + scylla_cluster_crd + contributing + +Scylla Operator is an open source project which helps users of Scylla Open Source and Scylla Enterprise run Scylla on Kubernetes (K8s) +The Scylla operator manages Scylla clusters deployed to Kubernetes and automates tasks related to operating a Scylla cluster, like installation, out and downscale, rolling upgrades. + +.. image:: logo.png + :width: 200pt + +For the latest status of the project, and reports issue, see the Github Project. Also check out the K8s Operator lesson on Scylla University. + +scylla-operator is a Kubernetes Operator for managing Scylla clusters. + +Currently it supports: + +* Deploying multi-zone clusters +* Scaling up or adding new racks +* Scaling down +* Monitoring with Prometheus and Grafana +* Integration with `Scylla Manager `_ +* Dead node replacement +* Version Upgrade +* Backup +* Repairs +* Autohealing +* Monitoring with Prometheus and Grafana + +**Choose a topic to begin**: + +* :doc:`Deploying Scylla on a Kubernetes Cluster ` +* :doc:`Deploying Scylla on EKS ` +* :doc:`Deploying Scylla on GKE ` +* :doc:`Deploying Scylla Manager on a Kubernetes Cluster ` +* :doc:`Deploying Scylla stack using Helm Charts ` +* :doc:`Setting up Monitoring using Prometheus and Grafana ` +* :doc:`Node operations ` +* :doc:`Performance tuning [Experimental] ` +* :doc:`Upgrade procedures ` +* :doc:`Releases ` +* :doc:`Known issues ` +* :doc:`Scylla Cluster Custom Resource Definition (CRD) ` +* :doc:`Contributing to the Scylla Operator Project ` diff --git a/v1.9/_sources/known_issues.md.txt b/v1.9/_sources/known_issues.md.txt new file mode 100644 index 00000000000..1af3a7bfdd1 --- /dev/null +++ b/v1.9/_sources/known_issues.md.txt @@ -0,0 +1,14 @@ +# Known issues + +### Scylla Manager does not boot up on Minikube + +If your Scylla Manager is failing to apply 8th migration (008_*), then apply fix for [TRUNCATE queries](#truncate-queries-does-not-work-on-minikube). + +### TRUNCATE queries does not work on Minikube + +The `TRUNCATE` queries requires [hairpinning](https://en.wikipedia.org/wiki/Hairpinning) to be enabled. On minikube this is disabled by default. + +To fix it execute the following command: +``` +minikube ssh sudo ip link set docker0 promisc on +``` diff --git a/v1.9/_sources/manager.md.txt b/v1.9/_sources/manager.md.txt new file mode 100644 index 00000000000..470ef951202 --- /dev/null +++ b/v1.9/_sources/manager.md.txt @@ -0,0 +1,258 @@ +# Deploying Scylla Manager on a Kubernetes Cluster + +Scylla Manager is a product for database operations automation, +it can schedule tasks such as repairs and backups. +Scylla Manager can manage multiple Scylla clusters and run cluster-wide tasks +in a controlled and predictable way. + +Scylla Manager is available for Scylla Enterprise customers and Scylla Open Source users. +With Scylla Open Source, Scylla Manager is limited to 5 nodes. +See the Scylla Manager [Proprietary Software License Agreement](https://www.scylladb.com/scylla-manager-software-license-agreement/) for details. + +## Prerequisites + +* Kubernetes cluster +* Scylla Operator - see [generic guide](generic.md) + +## Architecture + +Scylla Manager in K8s consist of: +- Dedicated Scylla Cluster + + Scylla Manager persists its state to a Scylla cluster. +Additional small single node cluster is spawned in the Manager namespace. + +- Scylla Manager Controller + + Main mission of Controller is to watch changes of Scylla Clusters, and synchronize three states. + 1. What user wants - task definition in CRD. + 2. What Controller registered - Task name to Task ID mapping - CRD status. + 3. Scylla Manager task listing - internal state of Scylla Manager. + + When Scylla Cluster CRD is being deployed Controller will register it in Scylla Manager once cluster reaches desired node count. +Once Cluster is fully up and running it will schedule all tasks defined in Cluster CRD. +Controller also supports task updates and unscheduling. + +- Scylla Manager + + Regular Scylla Manager, the same used in cloud and bare metal deployments. + + + +## Deploy Scylla Manager + +Deploy the Scylla Manager using the following commands: + +```console +kubectl apply -f examples/common/manager.yaml +``` + +This will install the Scylla Manager in the `scylla-manager` namespace. +You can check if the Scylla Manager is up and running with: + +```console +kubectl -n scylla-manager get pods +NAME READY STATUS RESTARTS AGE +scylla-manager-cluster-manager-dc-manager-rack-0 2/2 Running 0 37m +scylla-manager-controller-0 1/1 Running 0 28m +scylla-manager-scylla-manager-7bd9f968b9-w25jw 1/1 Running 0 37m +``` + +As you can see there are three pods: +* `scylla-manager-cluster-manager-dc-manager-rack-0` - is a single node Scylla cluster. +* `scylla-manager-controller-0` - Scylla Manager Controller. +* `scylla-manager-scylla-manager-7bd9f968b9-w25jw` - Scylla Manager. + +To see if Scylla Manager is fully up and running we can check their logs. +To do this, execute following command: + + ```console +kubectl -n scylla-manager logs scylla-manager-controller-0 +``` + +The output should be something like: +```console +{"L":"INFO","T":"2020-09-23T11:25:27.882Z","M":"Scylla Manager Controller started","version":"","build_date":"","commit":"","built_by":"","go_version":"","options":{"Name":"scylla-manager-controller-0","Namespace":"scylla-manager","LogLevel":"debug","ApiAddress":"http://127.0.0.1:5080/api/v1"},"_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"} +{"L":"INFO","T":"2020-09-23T11:25:28.435Z","M":"Registering Components.","_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"} +``` + +To check logs of Scylla Manager itself, use following command: +```console +kubectl -n scylla-manager logs scylla-manager-scylla-manager-7bd9f968b9-w25jw +``` + +The output should be something like: + +```console +{"L":"INFO","T":"2020-09-23T11:26:53.238Z","M":"Scylla Manager Server","version":"2.1.2-0.20200816.76cc4dcc","pid":1,"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Using config","config":{"HTTP":"127.0.0.1:5080","HTTPS":"","TLSCertFile":"/var/lib/scylla-manager/scylla_manager.crt","TLSKeyFile":"/var/lib/scylla-manager/scylla_manager.key","TLSCAFile":"","Prometheus":":56090","PrometheusScrapeInterval":5000000000,"debug":"127.0.0.1:56112","Logger":{"Mode":"stderr","Level":"info","Development":false},"Database":{"Hosts":["scylla-manager-cluster-manager-dc-manager-rack-0.scylla-manager.svc"],"SSL":false,"User":"","Password":"","LocalDC":"","Keyspace":"scylla_manager","MigrateDir":"/etc/scylla-manager/cql","MigrateTimeout":30000000000,"MigrateMaxWaitSchemaAgreement":300000000000,"ReplicationFactor":1,"Timeout":600000000,"TokenAware":true},"SSL":{"CertFile":"","Validate":true,"UserCertFile":"","UserKeyFile":""},"Healthcheck":{"Timeout":250000000,"SSLTimeout":750000000},"Backup":{"DiskSpaceFreeMinPercent":10,"AgeMax":43200000000000},"Repair":{"SegmentsPerRepair":1,"ShardParallelMax":0,"ShardFailedSegmentsMax":100,"PollInterval":200000000,"ErrorBackoff":300000000000,"AgeMax":0,"ShardingIgnoreMsbBits":12}},"config_files":["/mnt/etc/scylla-manager/scylla-manager.yaml"],"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Checking database connectivity...","_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"} +``` + +If there are no errors in the logs, let's spin a Scylla Cluster. + +## Cluster registration + + +When the Scylla Manager is fully up and running, lets create a regular instance of Scylla cluster. + +See [generic tutorial](generic.md) to spawn your cluster. + +Note: If you already have some Scylla Clusters, after installing Manager they should be +automatically registered in Scylla Manager. + +Once cluster reaches desired node count, cluster status will be updated with ID under which it was registered in Manager. + + ```console +kubectl -n scylla describe Cluster + +[...] +Status: + Manager Id: d1d532cd-49f2-4c97-9263-25126532803b + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.0.0 +``` +You can use this ID to talk to Scylla Manager using `sctool` CLI installed in Scylla Manager Pod. +You can also use Cluster name in `namespace/cluster-name` format. + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list + +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b) +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮ +│ Task │ Arguments │ Next run │ Status │ +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤ +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b │ │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE │ +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd │ │ 23 Sep 20 14:29:57 CEST (+1m) │ NEW │ +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯ + +``` + +Scylla Manager by default registers recurring healhcheck tasks for Agent and for each of the enabled frontends (CQL, Alternator). + +In this task listing we can see CQL and REST healthchecks. + +## Task scheduling + +You can either define tasks prior Cluster creation, or for existing Cluster. +Let's edit already running cluster definition to add repair and backup task. +```console +kubectl -n scylla edit Cluster simple-cluster +``` + +Add following task definition to Cluster spec: +``` + repairs: + - name: "users repair" + keyspace: ["users"] + interval: "1d" + backup: + - name: "weekly backup" + location: ["s3:cluster-backups"] + retention: 3 + interval: "7d" + - name: "daily backup" + location: ["s3:cluster-backups"] + retention: 7 + interval: "1d" +``` + +For full task definition configuration consult [Scylla Cluster CRD](scylla_cluster_crd.md). + +**Note**: Scylla Manager Agent must have access to above bucket prior the update in order to schedule backup task. +Consult Scylla Manager documentation for details on how to set it up. + +Scylla Manager Controller will spot this change and will schedule tasks in Scylla Manager. + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list + +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b) +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮ +│ Task │ Arguments │ Next run │ Status │ +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤ +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b │ │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE │ +│ backup/275aae7f-c436-4fc8-bcec-479e65fb8372 │ -L s3:cluster-backups --retention 3 │ 23 Sep 20 14:28:58 CEST (+7d) │ NEW │ +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd │ │ 23 Sep 20 14:29:57 CEST (+1m) │ NEW │ +│ repair/d4946360-c29d-4bb4-8b9d-619ada495c2a │ │ 23 Sep 20 14:38:42 CEST │ NEW │ +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯ + +``` + +As you can see, we have two new tasks, weekly recurring backup, and one repair which should start shortly. + +To check progress of run you can use following command: + +```console +kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task progress --cluster d1d532cd-49f2-4c97-9263-25126532803b repair/d4946360-c29d-4bb4-8b9d-619ada495c2a +Status: RUNNING +Start time: 23 Sep 20 14:38:42 UTC +Duration: 13s +Progress: 2.69% +Datacenters: + - us-east-1 ++--------------------+-------+ +| system_auth | 8.06% | +| system_distributed | 0.00% | +| system_traces | 0.00% | ++--------------------+-------+ + +``` +Other tasks can be also tracked using the same command, but using different task ID. +Task IDs are present in Cluster Status as well as in task listing. + +## Clean Up + +To clean up all resources associated with Scylla Manager, you can run the commands below. + +**NOTE:** this will destroy your Scylla Manager database and delete all of its associated data. + +```console +kubectl delete -f examples/common/manager.yaml +``` + +## Troubleshooting + +**Manager is not running** + +If the Scylla Manager does not come up, the first step would be to examine the Manager and Controller logs: + +```console +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-controller +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-scylla-manager-7bd9f968b9-w25jw +``` + + +**My task wasn't scheduled** + +If your task wasn't scheduled, Cluster status will be updated with error messages for each failed task. +You can also consult Scylla Manager logs. + +Example: + +Following status describes error when backup task cannot be scheduled, due to lack of access to bucket: +```console +Status: + Backups: + Error: create backup target: location is not accessible: 10.100.16.62: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.100.16.62 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.107.193.33: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.107.193.33 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.109.197.60: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.109.197.60 and run "scylla-manager-agent check-location -L s3:manager-test --debug" + Id: 00000000-0000-0000-0000-000000000000 + Interval: 0 + Location: + s3:manager-test + Name: adhoc backup + Num Retries: 3 + Retention: 3 + Start Date: now + Manager Id: 2b9dbe8c-9daa-4703-a66d-c29f63a917c8 + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.0.0 +``` + +Because Controller is infinitely retrying to schedule each defined task, once permission issues will be resolved, +task should appear in task listing and Cluster status. \ No newline at end of file diff --git a/v1.9/_sources/migration.md.txt b/v1.9/_sources/migration.md.txt new file mode 100644 index 00000000000..cdd7a7e8522 --- /dev/null +++ b/v1.9/_sources/migration.md.txt @@ -0,0 +1,146 @@ +## Version migrations + + +### `v0.3.0` -> `v1.0.0` migration + +`v0.3.0` used a very common name as a CRD kind (`Cluster`). In `v1.0.0` this issue was solved by using less common kind +which is easier to disambiguate (`ScyllaCluster`). +***This change is backward incompatible, which means manual migration is needed.*** + +This procedure involves having two CRDs registered at the same time. We will detach Scylla Pods +from Scylla Operator for a short period to ensure that nothing is garbage collected when Scylla Operator is upgraded. +Compared to the [upgrade guide](upgrade.md) where full deletion is requested, this procedure shouldn't cause downtimes. +Although detaching resources from their controller is considered hacky. This means that you shouldn't run procedure +out of the box on production. Make sure this procedure works well multiple times on your staging environment first. + +***Read the whole procedure and make sure you understand what is going on before executing any of the commands!*** + +In case of any issues or questions regarding this procedure, you're welcomed on our [Scylla Users Slack](http://slack.scylladb.com/) +on #kubernetes channel. + +### Procedure + +1. Execute this whole procedure for each cluster sequentially. To get a list of existing clusters execute the following + ``` + kubectl -n scylla get cluster.scylla.scylladb.com + + NAME AGE + simple-cluster 30m + ``` + All below commands will use `scylla` namespace and `simple-cluster` as a cluster name. +1. Make sure you're using v1.0.0 tag: + ``` + git checkout v1.0.0 + ``` +1. Upgrade your `cert-manager` to `v1.0.0`. If you installed it from a static file from this repo, simply execute the following: + ``` + kubectl apply -f examples/common/cert-manager.yaml + ``` + If your `cert-manager` was installed in another way, follow official instructions on `cert-manager` website. +1. `examples/common/operator.yaml` file contains multiple resources. Extract **only** `CustomResourceDefinition` to separate file. +1. Install v1.0.0 CRD definition from file created in the previous step: + ``` + kubectl apply -f examples/common/crd.yaml + ``` +1. Save your existing `simple-cluster` Cluster definition to a file: + ``` + kubectl -n scylla get cluster.scylla.scylladb.com simple-cluster -o yaml > existing-cluster.yaml + ``` +1. Migrate `Kind` and `ApiVersion` to new values using: + ``` + sed -i 's/scylla.scylladb.com\/v1alpha1/scylla.scylladb.com\/v1/g' existing-cluster.yaml + sed -i 's/kind: Cluster/kind: ScyllaCluster/g' existing-cluster.yaml + ``` +1. Install migrated CRD instance + ``` + kubectl apply -f existing-cluster.yaml + ``` + At this point, we should have two CRDs describing your Scylla cluster, although the new one is not controlled by the Operator. +1. Get UUID of newly created ScyllaCluster resource: + ``` + kubectl -n scylla get ScyllaCluster simple-cluster --template="{{ .metadata.uid }}" + + 12a3678d-8511-4c9c-8a48-fa78d3992694 + ``` + Save output UUID somewhere, it will be referred as `` in commands below. + + ***Depending on your shell, you might get additional '%' sign at the end of UUID, make sure to remove it!*** + +1. Upgrade ClusterRole attached to each of the Scylla nodes to grant them permission to lookup Scylla clusters: + ``` + kubectl patch ClusterRole simple-cluster-member --type "json" -p '[{"op":"add","path":"/rules/-","value":{"apiGroups":["scylla.scylladb.com"],"resources":["scyllaclusters"],"verbs":["get"]}}]' + ``` + Amend role name according to your cluster name, it should look like `-member`. +1. Get a list of all Services associated with your cluster. First get list of all services: + ``` + kubectl -n scylla get svc -l "scylla/cluster=simple-cluster" + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 109m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.23.96 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 109m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.66.22 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 108m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.246.25 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 106m + + ``` +1. For each service, change its `ownerReference` to point to new CRD instance: + ``` + kubectl -n scylla patch svc --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":""}]' + ``` + Replace `` with Service name, and `` with saved UUID from one of the previous steps. +1. Get a list of all Services again to see if none was deleted. Check also "Age" column, it shouldn't be lower than previous result. + ``` + kubectl -n scylla get svc -l "scylla/cluster=simple-cluster" + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 110m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.23.96 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 110m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.66.22 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 109m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.246.25 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 107m + + ``` +1. Get a list of StatefulSets associated with your cluster: + ``` + kubectl -n scylla get sts -l "scylla/cluster=simple-cluster" + + NAME READY AGE + simple-cluster-us-east-1-us-east-1a 3/3 104m + ``` +1. For each StatefulSet from previous step, change its `ownerReference` to point to new CRD instance. + + ``` + kubectl -n scylla patch sts --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":""}]' + ``` + Replace `` with StatefulSet name, and `` with saved UUID from one of the previous steps. + +1. Now when all k8s resources bound to Scylla are attached to new CRD, we can remove 0.3.0 Operator and old CRD definition. + Checkout `v0.3.0` version, and remove Scylla Operator, and old CRD: + ``` + git checkout v0.3.0 + kubectl delete -f examples/generic/operator.yaml + ``` +1. Checkout `v1.0.0`, and install upgraded Scylla Operator: + ``` + git checkout v1.0.0 + kubectl apply -f examples/common/operator.yaml + ``` +1. Wait until Scylla Operator boots up: + ``` + kubectl -n scylla-operator-system wait --for=condition=ready pod --all --timeout=600s + ``` +1. Get a list of StatefulSets associated with your cluster: + ``` + kubectl -n scylla get sts -l "scylla/cluster=simple-cluster" + + NAME READY AGE + simple-cluster-us-east-1-us-east-1a 3/3 104m +1. For each StatefulSet from previous step, change its sidecar container image to `v1.0.0`, and wait until change will be propagated. This step will initiate a rolling restart of pods one by one. + ``` + kubectl -n scylla patch sts --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/initContainers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]' + kubectl -n scylla rollout status sts + ``` + Replace `` with StatefulSet name. +1. If you're using Scylla Manager, bump Scylla Manager Controller image to `v1.0.0` + ``` + kubectl -n scylla-manager-system patch sts scylla-manager-controller --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]' + ``` +1. Your Scylla cluster is now migrated to `v1.0.0`. diff --git a/v1.9/_sources/monitoring.md.txt b/v1.9/_sources/monitoring.md.txt new file mode 100644 index 00000000000..9f2651c5737 --- /dev/null +++ b/v1.9/_sources/monitoring.md.txt @@ -0,0 +1,180 @@ +# Monitoring + +Scylla Operator 1.8 introduced a new API resource `ScyllaDBMonitoring`, allowing users to deploy a managed monitoring +setup for their Scylla Clusters. + +```yaml +apiVersion: scylla.scylladb.com/v1alpha1 +kind: ScyllaDBMonitoring +metadata: + name: example +spec: + type: Platform + endpointsSelector: + matchLabels: + app.kubernetes.io/name: scylla + scylla-operator.scylladb.com/scylla-service-type: identity + scylla/cluster: replace-with-your-scyllacluster-name + components: + prometheus: + storage: + volumeClaimTemplate: + spec: + resources: + requests: + storage: 1Gi + grafana: + exposeOptions: + webInterface: + ingress: + ingressClassName: haproxy + dnsDomains: + - test-grafana.test.svc.cluster.local + annotations: + haproxy-ingress.github.io/ssl-passthrough: "true" +``` + +For details, refer to the below command: +```console +$ kubectl explain scylladbmonitorings.scylla.scylladb.com/v1alpha1 +``` + +## Deploy managed monitoring + +**Note**: as of v1.8, ScyllaDBMonitoring is experimental. The API is currently in version v1alpha1 and may change in future versions. + +### Requirements + +Before you can set up your ScyllaDB monitoring, you need Scylla Operator already installed in your Kubernetes cluster. +For more information on how to deploy Scylla Operator, see: +* [Deploying Scylla on a Kubernetes Cluster](generic.md) +* [Deploying Scylla stack using Helm Charts](helm.md) + +The above example of the monitoring setup also makes use of HAProxy Ingress and Prometheus Operator. +You can deploy them in your Kubernetes cluster using the provided third party examples. If you already have them deployed +in your cluster, you can skip the below steps. + +#### Deploy Prometheus Operator +Deploy Prometheus Operator using kubectl: +```console +$ kubectl -n prometheus-operator apply --server-side -f ./examples/third-party/prometheus-operator +``` + +##### Wait for Prometheus Operator to roll out +```console +$ kubectl -n prometheus-operator rollout status --timeout=5m deployments.apps/prometheus-operator +deployment "prometheus-operator" successfully rolled out +``` + +#### Deploy HAProxy Ingress +Deploy HAProxy Ingress using kubectl: +```console +$ kubectl -n haproxy-ingress apply --server-side -f ./examples/third-party/haproxy-ingress +``` + +##### Wait for HAProxy Ingress to roll out +```console +$ kubectl -n haproxy-ingress rollout status --timeout=5m deployments.apps/haproxy-ingress +deployment "haproxy-ingress" successfully rolled out +``` + +### Deploy ScyllaDBMonitoring + +First, update the `endpointsSelector` in `examples/monitoring/v1alpha1/scylladbmonitoring.yaml` with a label +matching your ScyllaCluster instance name. + +Deploy the monitoring setup using kubectl: +```console +$ kubectl -n scylla apply --server-side -f ./examples/monitoring/v1alpha1/scylladbmonitoring.yaml +``` + +Scylla Operator will notice the new ScyllaDBMonitoring object, and it will reconcile all necessary resources. + +#### Wait for ScyllaDBMonitoring to roll out +```console +$ kubectl wait --for='condition=Progressing=False' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met + +$ kubectl wait --for='condition=Degraded=False' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met + +$ kubectl wait --for='condition=Available=True' scylladbmonitorings.scylla.scylladb.com/example +scylladbmonitoring.scylla.scylladb.com/example condition met +``` + +#### Wait for Prometheus to roll out +```console +$ kubectl rollout status --timeout=5m statefulset.apps/prometheus-example +statefulset rolling update complete 1 pods at revision prometheus-example-65b89d55bb... +``` + +#### Wait for Grafana to roll out +```console +$ kubectl rollout status --timeout=5m deployments.apps/example-grafana +deployment "example-grafana" successfully rolled out +``` + +### Accessing Grafana + +For accessing Grafana service from outside the Kubernetes cluster we recommend using an Ingress, although there are many other ways to do so. +When using Ingress, what matters is to direct your packets to the ingress controller Service/Pods and have the correct TLS SNI field set by the caller when reaching out to the service, so it is routed properly, and your client can successfully validate the grafana serving certificate. +This is easier when you are using a real DNS domain that resolves to your Ingress controller's IP address but most clients and tools allow setting the SNI field manually. + +### Prerequisites + +To access Grafana, you first need to collect the serving CA and the credentials. + +```console +$ GRAFANA_SERVING_CERT="$( kubectl -n scylla get secret/example-grafana-serving-ca --template '{{ index .data "tls.crt" }}' | base64 -d )" +$ GRAFANA_USER="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "username" }}' | base64 -d )" +$ GRAFANA_PASSWORD="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "password" }}' | base64 -d )" +``` + +### Connecting through Ingress using a resolvable domain + +In production clusters, the Ingress controller and appropriate DNS records should be set up already. Often there is already a generic wildcard record like `*.app.mydomain` pointing to the Ingress controller's external IP. For custom service domains, it is usually a CNAME pointing to the Ingress controller's A record. + +Note: The ScyllaDBMonitoring example creates an Ingress object with `test-grafana.test.svc.cluster.local` DNS domain that you should adjust to your domain. Below examples use `example-grafana.apps.mydomain`. + +Note: To test a resolvable domain from your machine without creating DNS records, you can adjust `/etc/hosts` or similar. + +```console +$ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://example-grafana.apps.mydomain" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}" +200 +``` + +### Connecting through Ingress using an unresolvable domain + +To connect to an Ingress without a resolvable domain you first need to find out your Ingress controller's IP that can be resolved externally. Again, there are many ways to do so beyond the below examples. + +Unless stated otherwise, we assume your Ingress is running on port 443. + +```console +$ INGRESS_PORT=443 +``` + +#### Variants + +##### Ingress ExternalIP + +When you are running in a real cluster there is usually a cloud LoadBalancer or a bare metal alternative providing you with an externally reachable IP address. + +```console +$ INGRESS_IP="$( kubectl -n=haproxy-ingress get service/haproxy-ingress --template='{{ ( index .status.loadBalancer.ingress 0 ).ip }}' )" +``` + +##### Ingress NodePort + +NodePort is slightly less convenient, but it's available in development clusters as well. + +```console +$ INGRESS_IP="$( kubectl get nodes --template='{{ $internal_ip := "" }}{{ $external_ip := "" }}{{ range ( index .items 0 ).status.addresses }}{{ if eq .type "InternalIP" }}{{ $internal_ip = .address }}{{ else if eq .type "ExternalIP" }}{{ $external_ip = .address }}{{ end }}{{ end }}{{ if $external_ip }}{{ $external_ip }}{{ else }}{{ $internal_ip }}{{ end }}' )" +$ INGRESS_PORT="$( kubectl -n=haproxy-ingress get services/haproxy-ingress --template='{{ range .spec.ports }}{{ if eq .port 443 }}{{ .nodePort }}{{ end }}{{ end }}' )" +``` + +##### Connection + +```console +$ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://test-grafana.test.svc.cluster.local:${INGRESS_PORT}" --resolve "test-grafana.test.svc.cluster.local:${INGRESS_PORT}:${INGRESS_IP}" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}" +200 +``` diff --git a/v1.9/_sources/nodeoperations/automatic_cleanup.md.txt b/v1.9/_sources/nodeoperations/automatic_cleanup.md.txt new file mode 100644 index 00000000000..5e0535cca97 --- /dev/null +++ b/v1.9/_sources/nodeoperations/automatic_cleanup.md.txt @@ -0,0 +1,6 @@ +# Automatic cleanup and replacement in case when k8s node is lost + +In case when your k8s cluster loses one of the nodes due to incident or explicit removal, Scylla Pods may become unschedulable due to PVC node affinity. + +When `automaticOrphanedNodeCleanup` flag is enabled in your ScyllaCluster, Scylla Operator will perform automatic +node replacement of a Pod which lost his bound resources. diff --git a/v1.9/_sources/nodeoperations/index.rst.txt b/v1.9/_sources/nodeoperations/index.rst.txt new file mode 100644 index 00000000000..d5667b9a4f7 --- /dev/null +++ b/v1.9/_sources/nodeoperations/index.rst.txt @@ -0,0 +1,22 @@ +====================================== +Node operations using Scylla Operator +====================================== + +.. toctree:: + :hidden: + :maxdepth: 2 + + scylla_upgrade + replace_node + automatic_cleanup + maintenance_mode + restore + + +Choose a topic: + +* :doc:`Scylla version upgrade ` +* :doc:`Replace Scylla node ` +* :doc:`Automatic cleanup and replacement when k8s node is lost ` +* :doc:`Maintenance mode ` +* :doc:`Restore from backup ` \ No newline at end of file diff --git a/v1.9/_sources/nodeoperations/maintenance_mode.md.txt b/v1.9/_sources/nodeoperations/maintenance_mode.md.txt new file mode 100644 index 00000000000..c976ecc2b87 --- /dev/null +++ b/v1.9/_sources/nodeoperations/maintenance_mode.md.txt @@ -0,0 +1,19 @@ +# Maintenance mode + +When maintenance mode is enabled, readiness probe of Scylla Pod will always return failure and liveness probe will always succeed. This causes that Pod under maintenance +is being removed from K8s Load Balancer and DNS registry but Pod itself stays alive. + +This allows the Scylla Operator to interact with Scylla and Scylla dependencies inside the Pod. +For example user may turn off Scylla process, do something with the filesystem and bring the process back again. + +To enable maintenance mode add `scylla/node-maintenance` label to service in front of Scylla Pod. + +```bash +kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance="" +``` + +To disable, simply remove this label from service. + +```bash +kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance- +``` diff --git a/v1.9/_sources/nodeoperations/replace_node.md.txt b/v1.9/_sources/nodeoperations/replace_node.md.txt new file mode 100644 index 00000000000..3e6a8c7f024 --- /dev/null +++ b/v1.9/_sources/nodeoperations/replace_node.md.txt @@ -0,0 +1,74 @@ +# Replacing a Scylla node + +## Replacing a dead node +In the case of a host failure, it may not be possible to bring back the node to life. + +Replace dead node operation will cause the other nodes in the cluster to stream data to the node that was replaced. +This operation can take some time (depending on the data size and network bandwidth). + +_This procedure is for replacing one dead node. To replace more than one dead node, run the full procedure to completion one node at a time_ + +**Procedure** + +1. Verify the status of the node using `nodetool status` command, the node with status DN is down and need to be replaced + ```bash + kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status + Datacenter: us-east-1 + ===================== + Status=Up/Down + |/ State=Normal/Leaving/Joining/Moving + -- Address Load Tokens Owns Host ID Rack + UN 10.43.125.110 74.63 KB 256 ? 8ebd6114-969c-44af-a978-87a4a6c65c3e us-east-1a + UN 10.43.231.189 91.03 KB 256 ? 35d0cb19-35ef-482b-92a4-b63eee4527e5 us-east-1a + DN 10.43.43.51 74.77 KB 256 ? 1ffa7a82-c41c-4706-8f5f-4d45a39c7003 us-east-1a + ``` +1. Identify service which is bound to down node by checking IP address + ```bash + kubectl -n scylla get svc + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + simple-cluster-client ClusterIP None 9180/TCP 3h12m + simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.43.231.189 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h12m + simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.43.125.110 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h11m + simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.43.43.51 7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP 3h5m + ``` +1. Drain node which we would like to replace using. **This command may delete your data from local disks attached to given node!** + ```bash + kubectl drain gke-scylla-demo-default-pool-b4b390a1-6j12 --ignore-daemonsets --delete-local-data + ``` + + Pod which will be replaced should enter the `Pending` state + ```bash + kubectl -n scylla get pods + NAME READY STATUS RESTARTS AGE + simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 3h21m + simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 3h19m + simple-cluster-us-east-1-us-east-1a-2 0/2 Pending 0 8m14s + ``` +1. To being node replacing, add `scylla/replace=""` label to service bound to pod we are replacing. + ```bash + kubectl -n scylla label svc simple-cluster-us-east-1-us-east-1a-2 scylla/replace="" + ``` + Your failed Pod should be recreated on available k8s node + ```bash + kubectl -n scylla get pods + NAME READY STATUS RESTARTS AGE + simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 3h27m + simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 3h25m + simple-cluster-us-east-1-us-east-1a-2 1/2 Running 0 9s + ``` + Because other nodes in cluster must stream data to new node this operation might take some time depending on how much data your cluster stores. + After bootstraping is over, your new Pod should be ready to go. + Old one shouldn't be no longer visible in `nodetool status` + ```bash + kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status + Datacenter: us-east-1 + ===================== + Status=Up/Down + |/ State=Normal/Leaving/Joining/Moving + -- Address Load Tokens Owns Host ID Rack + UN 10.43.125.110 74.62 KB 256 ? 8ebd6114-969c-44af-a978-87a4a6c65c3e us-east-1a + UN 10.43.231.189 91.03 KB 256 ? 35d0cb19-35ef-482b-92a4-b63eee4527e5 us-east-1a + UN 10.43.191.172 74.77 KB 256 ? 1ffa7a82-c41c-4706-8f5f-4d45a39c7003 us-east-1a + ``` +1. Run the repair on the cluster to make sure that the data is synced with the other nodes in the cluster. + You can use [Scylla Manager](../manager.md) to run the repair. diff --git a/v1.9/_sources/nodeoperations/restore.md.txt b/v1.9/_sources/nodeoperations/restore.md.txt new file mode 100644 index 00000000000..b4d85573cff --- /dev/null +++ b/v1.9/_sources/nodeoperations/restore.md.txt @@ -0,0 +1,89 @@ +# Restore from backup + +This procedure will describe how to restore from backup taken using [Scylla Manager](../manager.md) to a fresh **empty** cluster of any size. + +First identify to which snapshot you want to restore. To get list of available snapshot execute following command on Scylla Manager Pod. +```bash +sctool backup list -c --all-clusters -L +``` + +Where: +* `CLUSTER_ID` - is a name of a cluster or ID under which ScyllaCluster was registered. You can find it in ScyllaCluster Status. +* `BACKUP_LOCATION` - is a location where backup is stored. For example, for bucket called `backups` stored in AWS S3, location is `s3:backups`. + +```bash +sctool backup list -c simple-cluster --all-clusters -L s3:backups +Snapshots: + - sm_20201227144037UTC (409MiB) + - sm_20201228145917UTC (434MiB) +Keyspaces: + - users (9 tables) + - system_auth (2 tables) + - system_distributed (3 tables) + - system_schema (13 tables) + - system_traces (5 tables) +``` + +To get the list of files use: + +```bash +sctool backup files -c -L -T +``` + +Where: +* `SNAPSHOT_TAG` - name of snapshot you want to restore. + +Before we start restoring the data, we have to restore the schema. +The first output line is a path to schemas archive, for example: +```bash +s3://backups/backup/schema/cluster/ed63b474-2c05-4f4f-b084-94541dd86e7a/task_287791d9-c257-4850-aef5-7537d6e69d90_tag_sm_20201228145917UTC_schema.tar.gz ./ +``` + +To download this archive you can use AWS CLI tool `aws s3 cp`. + +This archive contains a single CQL file for each keyspace in the backup. +```bash +tar -ztvf task_287791d9-c257-4850-aef5-7537d6e69d90_tag_sm_20201228145917UTC_schema.tar.gz +-rw------- 0/0 12671 2020-12-28 13:17 users.cql +-rw------- 0/0 2216 2020-12-28 13:17 system_auth.cql +-rw------- 0/0 921 2020-12-28 13:17 system_distributed.cql +-rw------- 0/0 12567 2020-12-28 13:17 system_schema.cql +-rw------- 0/0 4113 2020-12-28 13:17 system_traces.cql +``` + +Extract this archive and copy each schema file to one of the cluster Pods by: +```bash +kubectl -n scylla cp users.cql simple-cluster-us-east-1-us-east-1a-0:/tmp/users.cql -c scylla +``` + +To import schema simply execute: +```bash +kubectl -n scylla exec simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -f /tmp/users.cql +``` + +Once the schema is recreated we can proceed to downloading data files. + +First let's save a list of snapshot files to file called `backup_files.out`: + +```bash +kubectl -n scylla-manager exec deployment.apps/scylla-manager-controller -- sctool backup files -c simple-cluster -L s3:backups -T sm_20201228145917UTC > backup_files.out +``` + +We will be using `sstableloader` to restore data. `sstableloader` needs a specific directory structure to work namely: `//` +To create this directory structure and download all the files execute these commands: +```bash +mkdir snapshot +cd snapshot +# Create temporary directory structure. +cat ../backup_files.out | awk '{print $2}' | xargs mkdir -p +# Download snapshot files. +cat ../backup_files.out | xargs -n2 aws s3 cp +``` + +To load data into cluster pass cluster address to `sstableloader` together with path to data files and credentials: +```bash +sstableloader -d 'simple-cluster-us-east-1-us-east-1a-0.scylla.svc,simple-cluster-us-east-1-us-east-1a-1.scylla.svc,simple-cluster-us-east-1-us-east-1a-2.scylla.svc' ./users/data_0 --username scylla --password +``` + +Depending on how big is your data set, this operation may take some time. +Once it finishes, data from the snapshot is restored and you may clean up the host. diff --git a/v1.9/_sources/nodeoperations/scylla_upgrade.md.txt b/v1.9/_sources/nodeoperations/scylla_upgrade.md.txt new file mode 100644 index 00000000000..d39c9666c5e --- /dev/null +++ b/v1.9/_sources/nodeoperations/scylla_upgrade.md.txt @@ -0,0 +1,102 @@ +# Upgrading version of Scylla + +To upgrade Scylla version using Operator user have to modify existing ScyllaCluster definition. + +In this example cluster will be upgraded to version `4.4.5`. +```bash +kubectl -n scylla patch ScyllaCluster simple-cluster -p '{"spec":{"version": "4.4.5"}}' --type=merge +``` + +Operator supports two types of version upgrades: +1. Patch upgrade +1. Generic upgrade + + +**Patch upgrade** + +Patch upgrade is executed when only patch version change is detected according to [semantic versioning format](https://semver.org/). +Procedure simply rolls out a restart of whole cluster and upgrades Scylla container image for each node one by one. + +Example: `4.0.0 -> 4.0.1` + +**Generic upgrade** + +Generic upgrades are executed for the non patch version changes. + +Example: `4.0.0 -> 2020.1.0` or `4.0.0 -> 4.1.0` or even `4.0.0 -> nightly` + +User can observe current state of upgrade in ScyllaCluster status. +```bash +kubectl -n scylla describe ScyllaCluster simple-cluster +[...] +Status: + Racks: + us-east-1a: + Members: 3 + Ready Members: 3 + Version: 4.1.9 + Upgrade: + Current Node: simple-cluster-us-east-1-us-east-1a-2 + Current Rack: us-east-1a + Data Snapshot Tag: so_data_20201228135002UTC + From Version: 4.1.9 + State: validate_upgrade + System Snapshot Tag: so_system_20201228135002UTC + To Version: 4.2.2 +``` + +Each upgrade begins with taking a snapshot of `system` and `system_schema` keyspaces on all nodes in parallel. +Name of this snapshot tag is saved in upgrade status under `System Snapshot Tag`. + +Before nodes in rack are upgraded, underlying StatefulSet is changed to use `OnDelete` UpgradeStrategy. +This allows Operator have a full control over when Pod image is changed. + +When a node is being upgraded, [maintenance mode](#maintenance-mode) is enabled, then the node is drained and snapshot of all data keyspaces is taken. +Snapshot tag is saved under `Data Snapshot Tag` and is the same for all nodes during the procedure. +Once everything is set up, maintenance mode is disabled and Scylla Pod is deleted. Underlying StatefulSet will bring up a new +Pod with upgraded version. +Once Pod will become ready, data snapshot from this particular node is removed, and Operator moves to next node. + +Once every rack is upgraded, system snapshot is removed from all nodes in parallel and previous StatefulSet UpgradeStrategy is restored. +At this point, all your nodes should be already in desired version. + +Current state of upgrade can be traced using `Current Node`, `Current Rack` and `State` status fields. +* `Current Node` shows which node is being upgraded. +* `Current Rack` displays which rack is being upgraded. +* `State` contain information at which stage upgrade is. + +`State` can have following values: +* `begin_upgrade` - upgrade is starting +* `check_schema_agreement` - Operator waits until all nodes reach schema agreement. It waits for it for 1 minute, prints an error log message and check is retried. +* `create_system_backup` - system keyspaces snapshot is being taken +* `find_next_rack` - Operator finds out which rack must be upgraded next, decision is saved in `Current Rack` +* `upgrade_image_in_pod_spec` - Image and UpgradeStrategy is upgraded in underlying StatefulSet +* `find_next_node` - Operator finds out which node must be upgraded next, decision is saved in `Current Node` +* `enable_maintenance_mode` - maintenance mode is being enabled +* `drain_node` - node is being drained +* `backup_data` - snapshot of data keyspaces is being taken +* `disable_maintenance_mode` - maintenance mode is being disabled +* `delete_pod` - Scylla Pod is being deleted +* `validate_upgrade` - Operator validates if new pod enters Ready state and if Scylla version is upgraded +* `clear_data_backup` - snapshot of data keyspaces is being removed +* `clear_system_backup` - snapshot of system keyspaces is being removed +* `restore_upgrade_strategy` - restore UpgradeStrategy in underlying StatefulSet +* `finish_upgrade` - upgrade cleanup + +**Recovering from upgrade failure** + +Upgrade may get stuck on `validate_upgrade` stage. This happens when Scylla Pod refuses to properly boot up. + +To continue with upgrade, first turn off operator by scaling Operator replicas to zero: +```bash +kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=0 +``` +Then user have to manually resolve issue with Scylla by checking what is the root cause of a failure in Scylla container logs. +If needed data and system keyspaces SSTable snapshots are available on the node. You can check ScyllaCluster status for their names. + +Once issue is resolved and Scylla Pod is up and running (Pod is in Ready state), scale Operator back to two replicas: +```bash +kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=2 +``` + +Operator should continue upgrade process from where it left off. diff --git a/v1.9/_sources/performance.md.txt b/v1.9/_sources/performance.md.txt new file mode 100644 index 00000000000..4b0bbd96781 --- /dev/null +++ b/v1.9/_sources/performance.md.txt @@ -0,0 +1,95 @@ +# Performance tuning + +Scylla Operator 1.6 introduces a new experimental feature allowing users to optimize Kubernetes nodes. + +## Node tuning + +Starting from Operator 1.6, a new CRD called NodeConfig is available, allowing users to target Nodes which should be tuned. +When a Node is supposed to be optimized, the Scylla Operator creates a DaemonSet covering these Nodes. +Nodes matching the provided placement conditions will be subject to tuning. + +Below example NodeConfig tunes nodes having `scylla.scylladb.com/node-type=scylla` label: +``` +apiVersion: scylla.scylladb.com/v1alpha1 +kind: NodeConfig +metadata: + name: cluster +spec: + placement: + nodeSelector: + scylla.scylladb.com/node-type: scylla +``` +For more details about new CRD use: +``` +kubectl explain nodeconfigs.scylla.scylladb.com/v1alpha1 +``` + +For all optimizations we use a Python script available in the Scylla image called perftune. +Perftune executes the performance optmizations like tuning the kernel, network, disk devices, spreading IRQs across CPUs and more. + +Tuning consists of two separate optimizations: common node tuning, and tuning based on Scylla Pods and their resource assignment. +Node tuning is executed immediately. Pod tuning is executed when Scylla Pod lands on the same Node. + +Scylla works most efficently when it's pinned to CPU and not interrupted. +One of the most common causes of context-switching are network interrupts. Packets coming to a node need to be processed, +and this requires CPU shares. + +On K8s we always have at least a couple of processes running on the node: kubelet, kubernetes provider applications, daemons etc. +These processes require CPU shares, so we cannot dedicate entire node processing power to Scylla, we need to leave space for others. +We take advantage of it, and we pin IRQs to CPUs not used by any Scylla Pods exclusively. + +Tuning resources are created in a special namespace called `scylla-operator-node-tuning`. + +The tuning is applied only to pods with `Guaranteed` QoS class. Please double check your ScyllaCluster resource specification +to see if it meets all conditions. + +## Kubernetes tuning + +By default, the kubelet uses the CFS quota to enforce pod CPU limits. +When the node runs many CPU-bound pods, the workload can move around different CPU cores depending on whether the pod +is throttled and which CPU cores are available. +However, kubelet may be configured to assign CPUs exclusively, by setting the CPU manager policy to static. + +Setting up kubelet configuration is provider specific. Please check the docs for your distribution or talk to your +provider. + +Only pods within the [Guaranteed QoS class](https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed)) can take advantage of this option. +When such pod lands on a Node, kubelet will pin them to specific CPUs, and those won't be part of the shared pool. + +In our case there are two requirements each ScyllaCluster must fulfill to receive a Guaranteed QoS class: +* resource request and limits must be equal or only limits have to be provided +* agentResources must be provided and their requests and limits must be equal, or only limits have to be provided + +An example of such a ScyllaCluster that receives a Guaranteed QoS class is below: + +``` +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: guaranteed-cluster + namespace: scylla +spec: + version: 4.5.1 + agentVersion: 2.5.2 + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 3 + storage: + capacity: 500Gi + agentResources: + requests: + cpu: 1 + memory: 1G + limits: + cpu: 1 + memory: 1G + resources: + requests: + cpu: 4 + memory: 16G + limits: + cpu: 4 + memory: 16G +``` \ No newline at end of file diff --git a/v1.9/_sources/releases.md.txt b/v1.9/_sources/releases.md.txt new file mode 100644 index 00000000000..05387dae5e1 --- /dev/null +++ b/v1.9/_sources/releases.md.txt @@ -0,0 +1,57 @@ +# Releases + +## Schedule +We are aiming to ship a new release approximately every 6 weeks. The following release schedule is only advisory, there are no commitments made to hitting these dates. + +| Release | Code freeze | General availability | +|:-------:|:-----------:|:--------------------:| +| 1.9 | 2022-03-01 | 2021-03-08 | + +## Supported releases +We support the latest 2 releases of the operator to give everyone time to upgrade. + +| Release | General availability | Support ends | +|:-------:|:--------------------:|:---------------:| +| 1.8 | 2023-01-25 | Release of 1.10 | +| 1.7 | 2022-01-27 | Release of 1.9 | +| 1.6 | 2021-12-03 | 2023-01-25 | +| 1.5 | 2021-09-16 | 2022-01-27 | +| 1.4 | 2021-08-10 | 2021-12-03 | +| 1.3 | 2021-06-17 | 2021-09-16 | +| 1.2 | 2021-05-06 | 2021-08-10 | +| 1.1 | 2021-03-22 | 2021-06-17 | +| 1.0 | 2021-01-21 | 2021-05-06 | + +### Backport policy +Usually, only important bug fixes are eligible for being backported. +This may depend on the situation and assessment of the maintainers. + +## CI/CD +We use [GitHub actions](https://github.com/scylladb/scylla-operator/actions/workflows/go.yaml?query=branch%3Amaster+event%3Apush) for our CI/CD. Every merge to a supported branch, or a creation of a tag will automatically trigger a job to build, test and publish the container image and other artifacts like helm charts. Before we publish any image, it must pass the e2e suite. + +### Automated promotions + +| Git reference | Type | Container image | +| :----------------: | :----: | :--------------------------------------------------: | +| **master** | branch | docker.io/scylladb/scylla-operator:**latest** | +| **vX.Y** | branch | docker.io/scylladb/scylla-operator:**X.Y** | +| **vX.Y.Z** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z** | +| **vX.Y.Z-alpha.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-alpha.N** | +| **vX.Y.Z-beta.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-beta.N** | +| **vX.Y.Z-rc.N** | tag | docker.io/scylladb/scylla-operator:**X.Y.Z-rc.N** | + +### Generally available +GA images aren't build from scratch but rather promoted from an existing release candidates. When we decide a release candidate has the acceptable quality and QA sings it off, the release candidate is promoted to become the GA release. This makes sure the image has exactly the same content and SHA as the tested release candidate. + +## Support matrix + +Support matrix table shows the version requirements for a particular **scylla-operator** version. Be sure to match these requirements, otherwise some functionality will not work. + +| | v1.9 | v1.8 | v1.7 | v1.6 | v1.5 | v1.4 | v1.3 | v1.2 | v1.1 | v1.0 | +|:-----------------:|:----------:|:----------:|:-----------------:|:--------------------:|:-----------:|:-----------:|:----------:|:----------:|:----------:|:----------:| +| Kubernetes | `>=1.21` | `>=1.21` | `>=1.20 && <1.25` | `>=1.19.10 && <1.25` | `>=1.19.10` | `>=1.19.10` | `>=1.19` | `>=1.19` | `>=1.11` | `>=1.11` | +| CRI API | `v1` | `v1alpha2` | `v1alpha2` | `v1alpha2` | | | | | | | +| Scylla OS | `>=5.0` | `>=5.0` | `>=4.3` | `>=4.3` | `>=4.3` | `>=4.3` | `>=4.2` | `>=4.2` | `>=4.0` | `>=4.0` | +| Scylla Enterprise | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2021.1` | `>=2020.1` | `>=2020.1` | `>=2020.1` | `>=2020.1` | +| Scylla Manager | `>=2.6` | `>=2.6` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | `>=2.2` | +| Scylla Monitoring | `>=4.0` | `>=4.0` | `>=3.0` | `>=3.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | `>=1.0` | diff --git a/v1.9/_sources/scylla_cluster_crd.md.txt b/v1.9/_sources/scylla_cluster_crd.md.txt new file mode 100644 index 00000000000..75d34f1a028 --- /dev/null +++ b/v1.9/_sources/scylla_cluster_crd.md.txt @@ -0,0 +1,188 @@ +# Scylla Cluster CRD + +Scylla database clusters can be created and configured using the `clusters.scylla.scylladb.com` custom resource definition (CRD). + +Please refer to the the [user guide walk-through](generic.md) for deployment instructions. +This page will explain all the available configuration options on the Scylla CRD. + +## Sample + +```yaml +apiVersion: scylla.scylladb.com/v1 +kind: ScyllaCluster +metadata: + name: simple-cluster + namespace: scylla +spec: + version: 2.3.1 + repository: scylladb/scylla + developerMode: true + cpuset: false + automaticOrphanedNodeCleanup: true + repairs: + - name: "weekly us-east-1 repair" + intensity: "2" + interval: "7d" + dc: ["us-east-1"] + backups: + - name: "daily users backup" + rateLimit: ["50"] + location: ["s3:cluster-backups"] + interval: "1d" + keyspace: ["users"] + - name: "weekly full cluster backup" + rateLimit: ["50"] + location: ["s3:cluster-backups"] + interval: "7d" + datacenter: + name: us-east-1 + racks: + - name: us-east-1a + members: 3 + storage: + capacity: 500G + storageClassName: local-raid-disks + resources: + requests: + cpu: 8 + memory: 32Gi + limits: + cpu: 8 + memory: 32Gi + placement: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: failure-domain.beta.kubernetes.io/region + operator: In + values: + - us-east-1 + - key: failure-domain.beta.kubernetes.io/zone + operator: In + values: + - us-east-1a + tolerations: + - key: role + operator: Equal + value: scylla-clusters + effect: NoSchedule +``` + +## Settings Explanation + +### Cluster Settings + +* `version`: The version of Scylla to use. It is used as the image tag to pull. +* `agentVersion`: The version of Scylla Manager Agent to use. It is used as the image tag to pull. +* `repository`: Optional field. Specifies a custom image repo. If left unset, the official docker hub repo is used (scylladb/scylla). +* `agentRepository`: Optional field. Specifies a custom Scylla Manager Agent image repo. If left unset, the official docker hub repo is used (scylladb/scylla). +* `developerMode`: Optional field. If it's true, then Scylla is started in [developer mode](https://www.scylladb.com/2016/09/13/test-dev-env/). This setting is for shared test/dev environments. +* `cpuset`: Optional field. If it's true, then the operator will start Scylla with cpu pinning for maximum performance. For this to work, you need to set the kubelet to use the [static cpu policy](https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/) and only specify limits in resources. +* `automaticOrphanedNodeCleanup`: Optional field. Controls if automatic orphan node cleanup should be performed. +* `alternator`: Optional field. Defines Alternator configuration. + * `port`: Port on which to bind to Alternator API. + * `writeIsolation`: *required* Desired write isolation. +* `genericUpgrade`: Optional field. Defines GenericUpgrade configuration. + * `failureStrategy`: specifies which logic is executed when upgrade failure happens. Currently only `Retry` is supported. + * `pollInterval`: specifies how often upgrade logic polls on state updates. + Increasing this value should lower number of requests sent to the kube-apiserver, but it may affect + overall time spent during upgrade. +* `datacenter`: Datacenter definition. +* `sysctls`: Optional field. Sysctl properties to be applied during initialization. +* `scyllaArgs`: Optional field. Command line argument passed to Scylla container image. Note: not all Scylla versions support it. +* `network`: Optional field. Allows to customize network parameters. + * `hostNetworking`: controls if host networking should be enabled. + * `dnsPolicy`: controls Scylla Pod DNS Policy. See [details](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy). +* `repairs`: Optional field. Repair tasks definitions. See `Scylla Manager settings` for details. +* `backups`: Optional field. Repair tasks definitions. See `Scylla Manager settings` for details. + + +In the Scylla model, each cluster contains datacenters and each datacenter contains racks. At the moment, the operator only supports single datacenter setups. + +### Scylla Manager settings + +Tasks are scheduled only when Scylla Manager is deployed in K8s cluster. + +Repairs: +* `name` - **required** - human readable name of the task. It must be unique across all tasks. +* `startDate` - specifies the task start date expressed in the RFC3339 format or `now[+duration]`, e.g. `now+3d2h10m`, +valid units are d, h, m, s (default "now"). +* `interval` - Optional field. Task schedule interval e.g. `3d2h10m`, valid units are d, h, m, s (default "0"). +* `numRetries` - Optional field. The number of times a scheduled task will retry to run before failing (default 3). +* `dc` - Optional field. A list of datacenter glob patterns, e.g. `["dc1", "!otherdc*"]` used to specify the DCs to include or exclude from backup. +* `failFast` - Optional field. Stop repair on first error. +* `intensity` - Optional field. Specifies how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. + If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). + Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. + Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. + For Scylla clusters that **do not support row-level repair**, intensity can be a decimal between (0,1). + In that case it specifies percent of shards that can be repaired in parallel on a repair master node. + For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1. + **Intensity is a number passed as string due to lack of support for float values in k8s controller runtime** +* `parallel` - Optional field. Specifies the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). + Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. + The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. + The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2. +* `keyspace` - Optional field. A list of keyspace/tables glob patterns, e.g. `["keyspace", "!keyspace.table_prefix_*"]` +used to include or exclude keyspaces from repair. +* `smallTableThreshold` - Optional field. Enable small table optimization for tables of size lower than given threshold. +Supported units `[B, MiB, GiB, TiB]` (default `"1GiB"`). + +Backups: + +* `name` - **required** - human readable name of the task. It must be unique across all tasks. +* `startDate` - Optional field. Specifies the task start date expressed in the RFC3339 format or `now[+duration]`, e.g. `now+3d2h10m`, +valid units are d, h, m, s (default "now"). +* `interval` - Optional field. task schedule interval e.g. `3d2h10m`, valid units are d, h, m, s (default "0"). +* `numRetries` - Optional field. the number of times a scheduled task will retry to run before failing (default 3). +* `dc` - Optional field. A list of datacenter glob patterns, e.g. `["dc1","!otherdc*"]` used to specify the DCs to include or exclude from backup. +* `keyspace` - Optional field. A list of keyspace/tables glob patterns, e.g. `["keyspace","!keyspace.table_prefix_*"]` used to include or exclude keyspaces from backup. +* `location` - Optional field. A list of backup locations in the format `[:]:` ex. `s3:my-bucket`. +The `:` part is optional and is only needed when different datacenters are being used to upload data to different locations. +`` Optional field. must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. +The only supported storage at the moment are `s3` and `gcs`. +* `rateLimit` - Optional field. A list of megabytes (MiB) per second rate limits expressed in the format `[:]`. +The `:` part is optional and only needed when different datacenters need different upload limits. +Set to 0 for no limit (default 100). +* `retention` - Optional field. The number of backups which are to be stored (default 3). +* `snapshotParallel` - Optional field. A list of snapshot parallelism limits in the format `[:]`. +The `:` part is optional and allows for specifying different limits in selected datacenters. +If The `:` part is not set, the limit is global (e.g. `["dc1:2,5"]`) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters. +* `uploadParallel` - Optional field. A list of upload parallelism limits in the format `[:]`. +The `:` part is optional and allows for specifying different limits in selected datacenters. +If The `:` part is not set the limit is global (e.g. `["dc1:2,5"]`) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters. + + +### Datacenter Settings + +* `name`: Name of the datacenter. Usually, a datacenter corresponds to a region. +* `racks`: List of racks for the specific datacenter. + +### Rack Settings + +* `name`: Name of the rack. Usually, a rack corresponds to an availability zone. +* `members`: Number of Scylla members for the specific rack. (In Scylla documentation, they are called nodes. We don't call them nodes to avoid confusion as a Scylla Node corresponds to a Kubernetes Pod, not a Kubernetes Node). +* `storage`: Defines the specs of the underlying storage. + * `capacity`: Capacity of the PersistentVolume to request. + * `storageClassName`: Optional field. [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) of PersistentVolume to request. +* `resources`: Defines the CPU and RAM resources for the Scylla Pods. + * `requests`: The minimum amount of resources needed to run a Scylla container. + * `cpu`: CPU requests. + * `memory`: RAM requests. + * `limits`: The maximum amount of resources that can be used by a Scylla container. + * `cpu`: CPU limits. + * `memory`: RAM limits. +* `agentResources`: Optional field. Defines the CPU and RAM resources for the Scylla Manager Agent container. See `resources` for details. +* `volumes`: Optional field. Defines volumes available in Scylla Pod. See [details](https://kubernetes.io/docs/concepts/storage/volumes/). +* `volumeMounts`: Optional field. Defines which volumes will be attached to Scylla container. +* `agentVolumeMounts`: Optional field. Defines which volumes will be attached to Agent container. +* `scyllaConfig`: Optional field. name of custom config map which will be merged with Scylla config. +* `scyllaAgentConfig`: Optional field. name of custom secret which will be merged with Scylla Manager Agent config. +* `placement`: Optional field. Defines the placement of Scylla Pods. Has the following subfields: + * [`nodeAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature) + * [`podAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature) + * [`podAntiAffinity`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature) + * [`tolerations`](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration) diff --git a/v1.9/_sources/upgrade.md.txt b/v1.9/_sources/upgrade.md.txt new file mode 100644 index 00000000000..ab14157256b --- /dev/null +++ b/v1.9/_sources/upgrade.md.txt @@ -0,0 +1,184 @@ +# Upgrade of Scylla Operator + +This page describes Scylla Operator upgrade procedures. +There are two generic update procedures - via Helm and via kubectl. Before upgrading, please check this page to find out +if your target version requires additional upgrade steps. + +## Upgrade via Helm + +Helm doesn't support managing CustomResourceDefinition resources ([#5871](https://github.com/helm/helm/issues/5871), [#7735](https://github.com/helm/helm/issues/7735)) +These are only created on first install and never updated. In order to update them, users have to do it manually. + +Replace `` with the name of your Helm release for Scylla Operator and replace `` with the version number you want to install: +1. Make sure Helm chart repository is up-to-date: + ``` + helm repo add scylla-operator https://storage.googleapis.com/scylla-operator-charts/stable + helm repo update + ``` +2. Update CRD resources. We recommend using `--server-side` flag for `kubectl apply`, if your version supports it. + ``` + tmpdir=$( mktemp -d ) \ + && helm pull scylla-operator/scylla-operator --version --untar --untardir "${tmpdir}" \ + && find "${tmpdir}"/scylla-operator/crds/ -name '*.yaml' -printf '-f=%p ' \ + | xargs kubectl apply + ``` +3. Update Scylla Operator + ``` + helm upgrade --version scylla-operator/scylla-operator + ``` + +## Upgrade via kubectl + +Replace `` with the version number you want to install: + +1. Checkout source code of version you want to use: + ``` + git checkout + ``` +2. Manifests use rolling minor version tag, you may want to pin it to specific version: + ``` + find deploy/operator -name "*.yaml" | xargs sed --follow-symlinks -i -E "s^docker.io/scylladb/scylla-operator:[0-9]+\.[0-9]+^docker.io/scylladb/scylla-operator:^g" + ``` +3. Update Scylla Operator. We recommend using `--server-side` flag for `kubectl apply`, if your version supports it. + ``` + kubectl apply -f deploy/operator + ``` + +--- + +## `v1.2.0` -> `v1.3.0` + +Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure. + +1. Checkout source code of v1.3.0: + ``` + git checkout v1.3.0 + ``` +1. Update Scylla Operator from deploy directory: + ``` + kubectl -n scylla-operator apply -f deploy/operator + ``` +1. Wait until Scylla Operator is up and running: + ``` + kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com + kubectl -n scylla-operator rollout status deployment.apps/scylla-operator + ``` + +## `v1.1.0` -> `v1.2.0` + +1.2.0 release brought a lot of changes to the Scylla Operator deployment process. +To properly update Scylla Operator one must delete old objects and install updated ones. + +Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure. + +1. Checkout source code of v1.2.0: + ``` + git checkout v1.2.0 + ``` +1. Remove old scylla operator namespace - in our case it's called `scylla-operator-system`: + ``` + kubectl delete namespace scylla-operator-system --wait=true + ``` +1. Remove old webhooks: + ``` + kubectl delete MutatingWebhookConfiguration scylla-operator-mutating-webhook-configuration + kubectl delete ValidatingWebhookConfiguration scylla-operator-validating-webhook-configuration + ``` +1. Install Scylla Operator from deploy directory: + ``` + kubectl -n scylla-operator apply -f deploy/operator + ``` +1. Wait until Scylla Operator is up and running: + ``` + kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com + kubectl -n scylla-operator rollout status deployment.apps/scylla-operator + ``` + +## `v1.0.0` -> `v1.1.0` + +During this update we will change probes and image for Scylla Operator. +A new version brings an automation for upgrade of sidecar image, so a rolling restart of managed Scylla clusters is expected. + +1. Get name of StatefulSet managing Scylla Operator + ```shell + kubectl --namespace scylla-operator-system get sts --selector="control-plane=controller-manager" + + NAME READY AGE + scylla-operator-controller-manager 1/1 95m + ``` + +1. Change probes and used container image by applying following patch: + ```yaml + spec: + template: + spec: + containers: + - name: manager + image: docker.io/scylladb/scylla-operator:1.1.0 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + scheme: HTTP + readinessProbe: + $retainKeys: + - httpGet + httpGet: + path: /readyz + port: 8080 + scheme: HTTP + ``` + To apply above patch save it to file (`operator-patch.yaml` for example) and apply to Operator StatefulSet: + ```shell + kubectl -n scylla-operator-system patch sts scylla-operator-controller-manager --patch "$(cat operator-patch.yaml)" + ``` + + +## `v0.3.0` -> `v1.0.0` + +***Note:*** There's an experimental migration procedure available [here](migration.md). + +`v0.3.0` used a very common name as a CRD kind (`Cluster`). In `v1.0.0` this issue was solved by using less common +kind which is easier to disambiguate. (`ScyllaCluster`). +This change is backward incompatible, so Scylla cluster must be turned off and recreated from scratch. +In case you need to preserve your data, refer to backup and restore guide. + +1. Get list of existing Scylla clusters + ``` + kubectl -n scylla get cluster.scylla.scylladb.com + + NAME AGE + simple-cluster 30m + ``` +1. Delete each one of them + + ``` + kubectl -n scylla delete cluster.scylla.scylladb.com simple-cluster + ``` +1. Make sure you're on `v0.3.0` branch + ``` + git checkout v0.3.0 + ``` +1. Delete existing CRD and Operator + ``` + kubectl delete -f examples/generic/operator.yaml + ``` +1. Checkout `v1.0.0` version + ``` + git checkout v1.0.0 + ``` +1. Install new CRD and Scylla Operator + ``` + kubectl apply -f examples/common/operator.yaml + ``` +1. Migrate your existing Scylla Cluster definition. Change `apiVersion` and `kind` from: + ``` + apiVersion: scylla.scylladb.com/v1alpha1 + kind: Cluster + ``` + to: + ``` + apiVersion: scylla.scylladb.com/v1 + kind: ScyllaCluster + ``` +1. Once your cluster definition is ready, use `kubectl apply` to install fresh Scylla cluster. diff --git a/v1.9/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/v1.9/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000000..eb19f698afc --- /dev/null +++ b/v1.9/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/v1.9/_sphinx_design_static/design-tabs.js b/v1.9/_sphinx_design_static/design-tabs.js new file mode 100644 index 00000000000..36b38cf0d91 --- /dev/null +++ b/v1.9/_sphinx_design_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/v1.9/_static/basic.css b/v1.9/_static/basic.css new file mode 100644 index 00000000000..30fee9d0f76 --- /dev/null +++ b/v1.9/_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/v1.9/_static/check-solid.svg b/v1.9/_static/check-solid.svg new file mode 100644 index 00000000000..92fad4b5c0b --- /dev/null +++ b/v1.9/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v1.9/_static/clipboard.min.js b/v1.9/_static/clipboard.min.js new file mode 100644 index 00000000000..54b3c463811 --- /dev/null +++ b/v1.9/_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/v1.9/_static/copybutton.css b/v1.9/_static/copybutton.css new file mode 100644 index 00000000000..f1916ec7d1b --- /dev/null +++ b/v1.9/_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/v1.9/_static/copybutton.js b/v1.9/_static/copybutton.js new file mode 100644 index 00000000000..2ea7ff3e217 --- /dev/null +++ b/v1.9/_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/v1.9/_static/copybutton_funcs.js b/v1.9/_static/copybutton_funcs.js new file mode 100644 index 00000000000..dbe1aaad79c --- /dev/null +++ b/v1.9/_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/v1.9/_static/css/main.css b/v1.9/_static/css/main.css new file mode 100644 index 00000000000..65eb0a55363 --- /dev/null +++ b/v1.9/_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/v1.9/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/v1.9/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000000..eb19f698afc --- /dev/null +++ b/v1.9/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/v1.9/_static/design-tabs.js b/v1.9/_static/design-tabs.js new file mode 100644 index 00000000000..36b38cf0d91 --- /dev/null +++ b/v1.9/_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/v1.9/_static/doctools.js b/v1.9/_static/doctools.js new file mode 100644 index 00000000000..d06a71d7518 --- /dev/null +++ b/v1.9/_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/v1.9/_static/documentation_options.js b/v1.9/_static/documentation_options.js new file mode 100644 index 00000000000..7e4c114f212 --- /dev/null +++ b/v1.9/_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/v1.9/_static/file.png b/v1.9/_static/file.png new file mode 100644 index 00000000000..a858a410e4f Binary files /dev/null and b/v1.9/_static/file.png differ diff --git a/v1.9/_static/img/banner-background.svg b/v1.9/_static/img/banner-background.svg new file mode 100644 index 00000000000..f8520d5b3e4 --- /dev/null +++ b/v1.9/_static/img/banner-background.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v1.9/_static/img/favicon-228x228.png b/v1.9/_static/img/favicon-228x228.png new file mode 100644 index 00000000000..f30770c7edd Binary files /dev/null and b/v1.9/_static/img/favicon-228x228.png differ diff --git a/v1.9/_static/img/favicon-32x32.png b/v1.9/_static/img/favicon-32x32.png new file mode 100644 index 00000000000..aae1708f26f Binary files /dev/null and b/v1.9/_static/img/favicon-32x32.png differ diff --git a/v1.9/_static/img/favicon.ico b/v1.9/_static/img/favicon.ico new file mode 100644 index 00000000000..6c7484f082f Binary files /dev/null and b/v1.9/_static/img/favicon.ico differ diff --git a/v1.9/_static/img/icons/icon-about-team.svg b/v1.9/_static/img/icons/icon-about-team.svg new file mode 100644 index 00000000000..5448c7f007b --- /dev/null +++ b/v1.9/_static/img/icons/icon-about-team.svg @@ -0,0 +1 @@ +icon-about-team diff --git a/v1.9/_static/img/icons/icon-about-us-m.svg b/v1.9/_static/img/icons/icon-about-us-m.svg new file mode 100644 index 00000000000..09107d9520a --- /dev/null +++ b/v1.9/_static/img/icons/icon-about-us-m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.9/_static/img/icons/icon-about-us.svg b/v1.9/_static/img/icons/icon-about-us.svg new file mode 100644 index 00000000000..1b1fcc83e30 --- /dev/null +++ b/v1.9/_static/img/icons/icon-about-us.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.9/_static/img/icons/icon-alternator.svg b/v1.9/_static/img/icons/icon-alternator.svg new file mode 100644 index 00000000000..7c2b4ebae0d --- /dev/null +++ b/v1.9/_static/img/icons/icon-alternator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.9/_static/img/icons/icon-apps.svg b/v1.9/_static/img/icons/icon-apps.svg new file mode 100644 index 00000000000..7e93612026b --- /dev/null +++ b/v1.9/_static/img/icons/icon-apps.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-architecture.svg b/v1.9/_static/img/icons/icon-architecture.svg new file mode 100644 index 00000000000..67ebbc2f38c --- /dev/null +++ b/v1.9/_static/img/icons/icon-architecture.svg @@ -0,0 +1 @@ +icon-architecture diff --git a/v1.9/_static/img/icons/icon-benchmarks.svg b/v1.9/_static/img/icons/icon-benchmarks.svg new file mode 100644 index 00000000000..e1ce2c1d784 --- /dev/null +++ b/v1.9/_static/img/icons/icon-benchmarks.svg @@ -0,0 +1 @@ +icon-benchmarks diff --git a/v1.9/_static/img/icons/icon-blog.svg b/v1.9/_static/img/icons/icon-blog.svg new file mode 100644 index 00000000000..f4096cbf111 --- /dev/null +++ b/v1.9/_static/img/icons/icon-blog.svg @@ -0,0 +1 @@ +icon-blog2 diff --git a/v1.9/_static/img/icons/icon-careers.svg b/v1.9/_static/img/icons/icon-careers.svg new file mode 100644 index 00000000000..2a7c6ea0b74 --- /dev/null +++ b/v1.9/_static/img/icons/icon-careers.svg @@ -0,0 +1 @@ +icon-careers diff --git a/v1.9/_static/img/icons/icon-chevron-left.svg b/v1.9/_static/img/icons/icon-chevron-left.svg new file mode 100644 index 00000000000..3afa25c4812 --- /dev/null +++ b/v1.9/_static/img/icons/icon-chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.9/_static/img/icons/icon-chevron-right.svg b/v1.9/_static/img/icons/icon-chevron-right.svg new file mode 100644 index 00000000000..44eb829cdcb --- /dev/null +++ b/v1.9/_static/img/icons/icon-chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.9/_static/img/icons/icon-circe.svg b/v1.9/_static/img/icons/icon-circe.svg new file mode 100644 index 00000000000..875e4216707 --- /dev/null +++ b/v1.9/_static/img/icons/icon-circe.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-clock.svg b/v1.9/_static/img/icons/icon-clock.svg new file mode 100644 index 00000000000..8c924698089 --- /dev/null +++ b/v1.9/_static/img/icons/icon-clock.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-close.svg b/v1.9/_static/img/icons/icon-close.svg new file mode 100644 index 00000000000..d1162b73e73 --- /dev/null +++ b/v1.9/_static/img/icons/icon-close.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/v1.9/_static/img/icons/icon-cloud-docs.svg b/v1.9/_static/img/icons/icon-cloud-docs.svg new file mode 100644 index 00000000000..a9069bb6e5c --- /dev/null +++ b/v1.9/_static/img/icons/icon-cloud-docs.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-cloud.svg b/v1.9/_static/img/icons/icon-cloud.svg new file mode 100644 index 00000000000..cfb2318daef --- /dev/null +++ b/v1.9/_static/img/icons/icon-cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.9/_static/img/icons/icon-comparison.svg b/v1.9/_static/img/icons/icon-comparison.svg new file mode 100644 index 00000000000..49d809a5df4 --- /dev/null +++ b/v1.9/_static/img/icons/icon-comparison.svg @@ -0,0 +1 @@ +icon-comparison diff --git a/v1.9/_static/img/icons/icon-contact-us.svg b/v1.9/_static/img/icons/icon-contact-us.svg new file mode 100644 index 00000000000..9df3145dd21 --- /dev/null +++ b/v1.9/_static/img/icons/icon-contact-us.svg @@ -0,0 +1 @@ +icon-contact-us diff --git a/v1.9/_static/img/icons/icon-developers-blog.svg b/v1.9/_static/img/icons/icon-developers-blog.svg new file mode 100644 index 00000000000..ee804197a0b --- /dev/null +++ b/v1.9/_static/img/icons/icon-developers-blog.svg @@ -0,0 +1 @@ +icon-developers-blog diff --git a/v1.9/_static/img/icons/icon-docs.svg b/v1.9/_static/img/icons/icon-docs.svg new file mode 100644 index 00000000000..5501492f3e0 --- /dev/null +++ b/v1.9/_static/img/icons/icon-docs.svg @@ -0,0 +1 @@ +icon-docs diff --git a/v1.9/_static/img/icons/icon-enterprise-m.svg b/v1.9/_static/img/icons/icon-enterprise-m.svg new file mode 100644 index 00000000000..97be900b501 --- /dev/null +++ b/v1.9/_static/img/icons/icon-enterprise-m.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.9/_static/img/icons/icon-enterprise.svg b/v1.9/_static/img/icons/icon-enterprise.svg new file mode 100644 index 00000000000..ee1ac26283d --- /dev/null +++ b/v1.9/_static/img/icons/icon-enterprise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.9/_static/img/icons/icon-events.svg b/v1.9/_static/img/icons/icon-events.svg new file mode 100644 index 00000000000..ba5f2118644 --- /dev/null +++ b/v1.9/_static/img/icons/icon-events.svg @@ -0,0 +1 @@ +icon-events diff --git a/v1.9/_static/img/icons/icon-exclamation.svg b/v1.9/_static/img/icons/icon-exclamation.svg new file mode 100644 index 00000000000..a7eb4b77a42 --- /dev/null +++ b/v1.9/_static/img/icons/icon-exclamation.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v1.9/_static/img/icons/icon-expand.svg b/v1.9/_static/img/icons/icon-expand.svg new file mode 100644 index 00000000000..38065653675 --- /dev/null +++ b/v1.9/_static/img/icons/icon-expand.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/v1.9/_static/img/icons/icon-forum.svg b/v1.9/_static/img/icons/icon-forum.svg new file mode 100644 index 00000000000..37a709f7a8f --- /dev/null +++ b/v1.9/_static/img/icons/icon-forum.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-getting-started.svg b/v1.9/_static/img/icons/icon-getting-started.svg new file mode 100644 index 00000000000..702500be409 --- /dev/null +++ b/v1.9/_static/img/icons/icon-getting-started.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-glossary.svg b/v1.9/_static/img/icons/icon-glossary.svg new file mode 100644 index 00000000000..e8329c2afee --- /dev/null +++ b/v1.9/_static/img/icons/icon-glossary.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-home.svg b/v1.9/_static/img/icons/icon-home.svg new file mode 100644 index 00000000000..f0b9c25419c --- /dev/null +++ b/v1.9/_static/img/icons/icon-home.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-infoworld.svg b/v1.9/_static/img/icons/icon-infoworld.svg new file mode 100644 index 00000000000..906e87279c2 --- /dev/null +++ b/v1.9/_static/img/icons/icon-infoworld.svg @@ -0,0 +1 @@ +icon-infoworld diff --git a/v1.9/_static/img/icons/icon-integrations.svg b/v1.9/_static/img/icons/icon-integrations.svg new file mode 100644 index 00000000000..1ef0920d49e --- /dev/null +++ b/v1.9/_static/img/icons/icon-integrations.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-knowledge-base.svg b/v1.9/_static/img/icons/icon-knowledge-base.svg new file mode 100644 index 00000000000..884451270d2 --- /dev/null +++ b/v1.9/_static/img/icons/icon-knowledge-base.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-less.svg b/v1.9/_static/img/icons/icon-less.svg new file mode 100644 index 00000000000..3094127decf --- /dev/null +++ b/v1.9/_static/img/icons/icon-less.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v1.9/_static/img/icons/icon-live-test.svg b/v1.9/_static/img/icons/icon-live-test.svg new file mode 100644 index 00000000000..dcb5916c264 --- /dev/null +++ b/v1.9/_static/img/icons/icon-live-test.svg @@ -0,0 +1 @@ +icon-live-test diff --git a/v1.9/_static/img/icons/icon-mail-list.svg b/v1.9/_static/img/icons/icon-mail-list.svg new file mode 100644 index 00000000000..0e6192a352c --- /dev/null +++ b/v1.9/_static/img/icons/icon-mail-list.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-manager.svg b/v1.9/_static/img/icons/icon-manager.svg new file mode 100644 index 00000000000..02b4e425beb --- /dev/null +++ b/v1.9/_static/img/icons/icon-manager.svg @@ -0,0 +1 @@ +icon-manager diff --git a/v1.9/_static/img/icons/icon-memory-management.svg b/v1.9/_static/img/icons/icon-memory-management.svg new file mode 100644 index 00000000000..e34eb4504f7 --- /dev/null +++ b/v1.9/_static/img/icons/icon-memory-management.svg @@ -0,0 +1 @@ +icon-memory-management diff --git a/v1.9/_static/img/icons/icon-modeling.svg b/v1.9/_static/img/icons/icon-modeling.svg new file mode 100644 index 00000000000..97fa3a0e213 --- /dev/null +++ b/v1.9/_static/img/icons/icon-modeling.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-monitoring.svg b/v1.9/_static/img/icons/icon-monitoring.svg new file mode 100644 index 00000000000..80b3787f668 --- /dev/null +++ b/v1.9/_static/img/icons/icon-monitoring.svg @@ -0,0 +1 @@ +icon-monitoring diff --git a/v1.9/_static/img/icons/icon-networking.svg b/v1.9/_static/img/icons/icon-networking.svg new file mode 100644 index 00000000000..40a3fd5f6f1 --- /dev/null +++ b/v1.9/_static/img/icons/icon-networking.svg @@ -0,0 +1 @@ +icon-networking diff --git a/v1.9/_static/img/icons/icon-news.svg b/v1.9/_static/img/icons/icon-news.svg new file mode 100644 index 00000000000..a952b59937d --- /dev/null +++ b/v1.9/_static/img/icons/icon-news.svg @@ -0,0 +1 @@ +icon-news diff --git a/v1.9/_static/img/icons/icon-newsletter.svg b/v1.9/_static/img/icons/icon-newsletter.svg new file mode 100644 index 00000000000..5b8d47eb157 --- /dev/null +++ b/v1.9/_static/img/icons/icon-newsletter.svg @@ -0,0 +1 @@ +icon-newsletter diff --git a/v1.9/_static/img/icons/icon-nsql-guides.svg b/v1.9/_static/img/icons/icon-nsql-guides.svg new file mode 100644 index 00000000000..60ebab37953 --- /dev/null +++ b/v1.9/_static/img/icons/icon-nsql-guides.svg @@ -0,0 +1 @@ +icon-nsql-guides diff --git a/v1.9/_static/img/icons/icon-open-source.svg b/v1.9/_static/img/icons/icon-open-source.svg new file mode 100644 index 00000000000..98c2ea7d5bf --- /dev/null +++ b/v1.9/_static/img/icons/icon-open-source.svg @@ -0,0 +1 @@ +icon-open-source diff --git a/v1.9/_static/img/icons/icon-operator.svg b/v1.9/_static/img/icons/icon-operator.svg new file mode 100644 index 00000000000..bb7d8d3ea86 --- /dev/null +++ b/v1.9/_static/img/icons/icon-operator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.9/_static/img/icons/icon-overview.svg b/v1.9/_static/img/icons/icon-overview.svg new file mode 100644 index 00000000000..515c1528a2a --- /dev/null +++ b/v1.9/_static/img/icons/icon-overview.svg @@ -0,0 +1 @@ +icon-overview diff --git a/v1.9/_static/img/icons/icon-partners.svg b/v1.9/_static/img/icons/icon-partners.svg new file mode 100644 index 00000000000..d0146fc4972 --- /dev/null +++ b/v1.9/_static/img/icons/icon-partners.svg @@ -0,0 +1 @@ +icon-partners diff --git a/v1.9/_static/img/icons/icon-plus.svg b/v1.9/_static/img/icons/icon-plus.svg new file mode 100644 index 00000000000..5757435085a --- /dev/null +++ b/v1.9/_static/img/icons/icon-plus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v1.9/_static/img/icons/icon-pricing.svg b/v1.9/_static/img/icons/icon-pricing.svg new file mode 100644 index 00000000000..74b01db1684 --- /dev/null +++ b/v1.9/_static/img/icons/icon-pricing.svg @@ -0,0 +1 @@ +icon-pricing$ diff --git a/v1.9/_static/img/icons/icon-release-notes.svg b/v1.9/_static/img/icons/icon-release-notes.svg new file mode 100644 index 00000000000..80c490c7b01 --- /dev/null +++ b/v1.9/_static/img/icons/icon-release-notes.svg @@ -0,0 +1 @@ +icon-release-notes diff --git a/v1.9/_static/img/icons/icon-resource-center.svg b/v1.9/_static/img/icons/icon-resource-center.svg new file mode 100644 index 00000000000..6e3ab08e792 --- /dev/null +++ b/v1.9/_static/img/icons/icon-resource-center.svg @@ -0,0 +1 @@ +icon-ressource-center diff --git a/v1.9/_static/img/icons/icon-roadmap.svg b/v1.9/_static/img/icons/icon-roadmap.svg new file mode 100644 index 00000000000..c8cbf67c8cf --- /dev/null +++ b/v1.9/_static/img/icons/icon-roadmap.svg @@ -0,0 +1 @@ +icon-roadmap-4 diff --git a/v1.9/_static/img/icons/icon-search.svg b/v1.9/_static/img/icons/icon-search.svg new file mode 100644 index 00000000000..81aae93eef6 --- /dev/null +++ b/v1.9/_static/img/icons/icon-search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v1.9/_static/img/icons/icon-slack.svg b/v1.9/_static/img/icons/icon-slack.svg new file mode 100644 index 00000000000..fc164ea1e77 --- /dev/null +++ b/v1.9/_static/img/icons/icon-slack.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-stack-overflow.svg b/v1.9/_static/img/icons/icon-stack-overflow.svg new file mode 100644 index 00000000000..bebe9b82742 --- /dev/null +++ b/v1.9/_static/img/icons/icon-stack-overflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v1.9/_static/img/icons/icon-summit.svg b/v1.9/_static/img/icons/icon-summit.svg new file mode 100644 index 00000000000..4b900bd0c0a --- /dev/null +++ b/v1.9/_static/img/icons/icon-summit.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/icons/icon-support.svg b/v1.9/_static/img/icons/icon-support.svg new file mode 100644 index 00000000000..a4228b34e86 --- /dev/null +++ b/v1.9/_static/img/icons/icon-support.svg @@ -0,0 +1 @@ +icon-support diff --git a/v1.9/_static/img/icons/icon-tech-talks.svg b/v1.9/_static/img/icons/icon-tech-talks.svg new file mode 100644 index 00000000000..df42b5522ba --- /dev/null +++ b/v1.9/_static/img/icons/icon-tech-talks.svg @@ -0,0 +1 @@ +icon-tech-talks diff --git a/v1.9/_static/img/icons/icon-testing.svg b/v1.9/_static/img/icons/icon-testing.svg new file mode 100644 index 00000000000..2fe54efdbc3 --- /dev/null +++ b/v1.9/_static/img/icons/icon-testing.svg @@ -0,0 +1 @@ +icon-testing diff --git a/v1.9/_static/img/icons/icon-thumbs-down.svg b/v1.9/_static/img/icons/icon-thumbs-down.svg new file mode 100644 index 00000000000..3e7bcd6d905 --- /dev/null +++ b/v1.9/_static/img/icons/icon-thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.9/_static/img/icons/icon-thumbs-up.svg b/v1.9/_static/img/icons/icon-thumbs-up.svg new file mode 100644 index 00000000000..226c44d853c --- /dev/null +++ b/v1.9/_static/img/icons/icon-thumbs-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v1.9/_static/img/icons/icon-tip.svg b/v1.9/_static/img/icons/icon-tip.svg new file mode 100644 index 00000000000..bf7aa6af840 --- /dev/null +++ b/v1.9/_static/img/icons/icon-tip.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/v1.9/_static/img/icons/icon-training.svg b/v1.9/_static/img/icons/icon-training.svg new file mode 100644 index 00000000000..08b95a88eda --- /dev/null +++ b/v1.9/_static/img/icons/icon-training.svg @@ -0,0 +1 @@ +icon-training diff --git a/v1.9/_static/img/icons/icon-triangle-down.svg b/v1.9/_static/img/icons/icon-triangle-down.svg new file mode 100644 index 00000000000..e8ae088106f --- /dev/null +++ b/v1.9/_static/img/icons/icon-triangle-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.9/_static/img/icons/icon-university.svg b/v1.9/_static/img/icons/icon-university.svg new file mode 100644 index 00000000000..f7547ab9599 --- /dev/null +++ b/v1.9/_static/img/icons/icon-university.svg @@ -0,0 +1 @@ +icon-university diff --git a/v1.9/_static/img/icons/icon-users-blog.svg b/v1.9/_static/img/icons/icon-users-blog.svg new file mode 100644 index 00000000000..47e56cddcf7 --- /dev/null +++ b/v1.9/_static/img/icons/icon-users-blog.svg @@ -0,0 +1 @@ +icon-users-blog diff --git a/v1.9/_static/img/icons/icon-warning.svg b/v1.9/_static/img/icons/icon-warning.svg new file mode 100644 index 00000000000..e4b1d40331b --- /dev/null +++ b/v1.9/_static/img/icons/icon-warning.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v1.9/_static/img/icons/icon-webinars.svg b/v1.9/_static/img/icons/icon-webinars.svg new file mode 100644 index 00000000000..5e9f5cd4270 --- /dev/null +++ b/v1.9/_static/img/icons/icon-webinars.svg @@ -0,0 +1 @@ +icon-webinars diff --git a/v1.9/_static/img/icons/icon-whitepapers.svg b/v1.9/_static/img/icons/icon-whitepapers.svg new file mode 100644 index 00000000000..3351e51d23c --- /dev/null +++ b/v1.9/_static/img/icons/icon-whitepapers.svg @@ -0,0 +1 @@ +icon-whitepapers diff --git a/v1.9/_static/img/icons/icon-workshop.svg b/v1.9/_static/img/icons/icon-workshop.svg new file mode 100644 index 00000000000..5206e58e986 --- /dev/null +++ b/v1.9/_static/img/icons/icon-workshop.svg @@ -0,0 +1 @@ + diff --git a/v1.9/_static/img/logo-docs.svg b/v1.9/_static/img/logo-docs.svg new file mode 100644 index 00000000000..4fff669cb6f --- /dev/null +++ b/v1.9/_static/img/logo-docs.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.9/_static/img/logo-scylla-horizontal-RGB.svg b/v1.9/_static/img/logo-scylla-horizontal-RGB.svg new file mode 100644 index 00000000000..b5022d7c4dc --- /dev/null +++ b/v1.9/_static/img/logo-scylla-horizontal-RGB.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.9/_static/img/mascots/404.jpg b/v1.9/_static/img/mascots/404.jpg new file mode 100644 index 00000000000..769fa0889f8 Binary files /dev/null and b/v1.9/_static/img/mascots/404.jpg differ diff --git a/v1.9/_static/img/mascots/scylla-3monsters.png b/v1.9/_static/img/mascots/scylla-3monsters.png new file mode 100644 index 00000000000..7c06d01674a Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-3monsters.png differ diff --git a/v1.9/_static/img/mascots/scylla-advisor-crystal.png b/v1.9/_static/img/mascots/scylla-advisor-crystal.png new file mode 100644 index 00000000000..d33fddd62f0 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-advisor-crystal.png differ diff --git a/v1.9/_static/img/mascots/scylla-alternator.svg b/v1.9/_static/img/mascots/scylla-alternator.svg new file mode 100644 index 00000000000..0462f893d5f --- /dev/null +++ b/v1.9/_static/img/mascots/scylla-alternator.svg @@ -0,0 +1 @@ +scylla-alternator diff --git a/v1.9/_static/img/mascots/scylla-cloud.svg b/v1.9/_static/img/mascots/scylla-cloud.svg new file mode 100644 index 00000000000..a6c6a26fc99 --- /dev/null +++ b/v1.9/_static/img/mascots/scylla-cloud.svg @@ -0,0 +1 @@ +scylla-cloud diff --git a/v1.9/_static/img/mascots/scylla-computer-3-monsters.png b/v1.9/_static/img/mascots/scylla-computer-3-monsters.png new file mode 100644 index 00000000000..d0368a7027b Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-computer-3-monsters.png differ diff --git a/v1.9/_static/img/mascots/scylla-computer-headset.png b/v1.9/_static/img/mascots/scylla-computer-headset.png new file mode 100644 index 00000000000..0cdadaa2167 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-computer-headset.png differ diff --git a/v1.9/_static/img/mascots/scylla-cup-number-one.png b/v1.9/_static/img/mascots/scylla-cup-number-one.png new file mode 100644 index 00000000000..e889f4e368e Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-cup-number-one.png differ diff --git a/v1.9/_static/img/mascots/scylla-docs.svg b/v1.9/_static/img/mascots/scylla-docs.svg new file mode 100644 index 00000000000..a5bce950c25 --- /dev/null +++ b/v1.9/_static/img/mascots/scylla-docs.svg @@ -0,0 +1 @@ +scylla-docs diff --git a/v1.9/_static/img/mascots/scylla-drivers.svg b/v1.9/_static/img/mascots/scylla-drivers.svg new file mode 100644 index 00000000000..6012e71679b --- /dev/null +++ b/v1.9/_static/img/mascots/scylla-drivers.svg @@ -0,0 +1 @@ +scylla-manager diff --git a/v1.9/_static/img/mascots/scylla-enterprise.svg b/v1.9/_static/img/mascots/scylla-enterprise.svg new file mode 100644 index 00000000000..a1aa0b46ac1 --- /dev/null +++ b/v1.9/_static/img/mascots/scylla-enterprise.svg @@ -0,0 +1 @@ +scylla-enterprise diff --git a/v1.9/_static/img/mascots/scylla-forklift-boxes.png b/v1.9/_static/img/mascots/scylla-forklift-boxes.png new file mode 100644 index 00000000000..f64c29e6c7c Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-forklift-boxes.png differ diff --git a/v1.9/_static/img/mascots/scylla-forklift-migration.png b/v1.9/_static/img/mascots/scylla-forklift-migration.png new file mode 100644 index 00000000000..d2f645c645a Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-forklift-migration.png differ diff --git a/v1.9/_static/img/mascots/scylla-gear.png b/v1.9/_static/img/mascots/scylla-gear.png new file mode 100644 index 00000000000..0f53b26afa5 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-gear.png differ diff --git a/v1.9/_static/img/mascots/scylla-hardhat.png b/v1.9/_static/img/mascots/scylla-hardhat.png new file mode 100644 index 00000000000..630f2d90942 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-hardhat.png differ diff --git a/v1.9/_static/img/mascots/scylla-headband.png b/v1.9/_static/img/mascots/scylla-headband.png new file mode 100644 index 00000000000..c87abe684d5 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-headband.png differ diff --git a/v1.9/_static/img/mascots/scylla-headset.png b/v1.9/_static/img/mascots/scylla-headset.png new file mode 100644 index 00000000000..ba52cd223db Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-headset.png differ diff --git a/v1.9/_static/img/mascots/scylla-hearts.png b/v1.9/_static/img/mascots/scylla-hearts.png new file mode 100644 index 00000000000..cef08c8654a Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-hearts.png differ diff --git a/v1.9/_static/img/mascots/scylla-looking-down.png b/v1.9/_static/img/mascots/scylla-looking-down.png new file mode 100644 index 00000000000..75cccbfdf12 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-looking-down.png differ diff --git a/v1.9/_static/img/mascots/scylla-looking-up.png b/v1.9/_static/img/mascots/scylla-looking-up.png new file mode 100644 index 00000000000..6f10405f218 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-looking-up.png differ diff --git a/v1.9/_static/img/mascots/scylla-magnifying-glass-fronting.png b/v1.9/_static/img/mascots/scylla-magnifying-glass-fronting.png new file mode 100644 index 00000000000..e368cae169c Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-magnifying-glass-fronting.png differ diff --git a/v1.9/_static/img/mascots/scylla-magnifying-glass.png b/v1.9/_static/img/mascots/scylla-magnifying-glass.png new file mode 100644 index 00000000000..74ad6695005 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-magnifying-glass.png differ diff --git a/v1.9/_static/img/mascots/scylla-manager.svg b/v1.9/_static/img/mascots/scylla-manager.svg new file mode 100644 index 00000000000..6ba9ed937c9 --- /dev/null +++ b/v1.9/_static/img/mascots/scylla-manager.svg @@ -0,0 +1 @@ +scylla-manager-2 diff --git a/v1.9/_static/img/mascots/scylla-monitor.svg b/v1.9/_static/img/mascots/scylla-monitor.svg new file mode 100644 index 00000000000..48bec7dde32 --- /dev/null +++ b/v1.9/_static/img/mascots/scylla-monitor.svg @@ -0,0 +1 @@ +scylla-monitor diff --git a/v1.9/_static/img/mascots/scylla-movement-fast.png b/v1.9/_static/img/mascots/scylla-movement-fast.png new file mode 100644 index 00000000000..956d1dd0e22 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-movement-fast.png differ diff --git a/v1.9/_static/img/mascots/scylla-movement.png b/v1.9/_static/img/mascots/scylla-movement.png new file mode 100644 index 00000000000..7ee2b043384 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-movement.png differ diff --git a/v1.9/_static/img/mascots/scylla-onpremise.png b/v1.9/_static/img/mascots/scylla-onpremise.png new file mode 100644 index 00000000000..3b2dc8f1a2c Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-onpremise.png differ diff --git a/v1.9/_static/img/mascots/scylla-opensource.svg b/v1.9/_static/img/mascots/scylla-opensource.svg new file mode 100644 index 00000000000..299e9cb9955 --- /dev/null +++ b/v1.9/_static/img/mascots/scylla-opensource.svg @@ -0,0 +1 @@ +Plan de travail 1 diff --git a/v1.9/_static/img/mascots/scylla-operator.svg b/v1.9/_static/img/mascots/scylla-operator.svg new file mode 100644 index 00000000000..655a450b2a4 --- /dev/null +++ b/v1.9/_static/img/mascots/scylla-operator.svg @@ -0,0 +1 @@ +scylla-operator diff --git a/v1.9/_static/img/mascots/scylla-plugin.png b/v1.9/_static/img/mascots/scylla-plugin.png new file mode 100644 index 00000000000..b28dc857ccf Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-plugin.png differ diff --git a/v1.9/_static/img/mascots/scylla-release-mascot.png b/v1.9/_static/img/mascots/scylla-release-mascot.png new file mode 100644 index 00000000000..09342ac6875 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-release-mascot.png differ diff --git a/v1.9/_static/img/mascots/scylla-repair.png b/v1.9/_static/img/mascots/scylla-repair.png new file mode 100644 index 00000000000..9b4c613e702 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-repair.png differ diff --git a/v1.9/_static/img/mascots/scylla-server.png b/v1.9/_static/img/mascots/scylla-server.png new file mode 100644 index 00000000000..96dc785298b Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-server.png differ diff --git a/v1.9/_static/img/mascots/scylla-sleeping.png b/v1.9/_static/img/mascots/scylla-sleeping.png new file mode 100644 index 00000000000..f88598e05ad Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-sleeping.png differ diff --git a/v1.9/_static/img/mascots/scylla-tall-measure.png b/v1.9/_static/img/mascots/scylla-tall-measure.png new file mode 100644 index 00000000000..6f0ca146c0d Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-tall-measure.png differ diff --git a/v1.9/_static/img/mascots/scylla-university.png b/v1.9/_static/img/mascots/scylla-university.png new file mode 100644 index 00000000000..b3d0621193f Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-university.png differ diff --git a/v1.9/_static/img/mascots/scylla-weights.png b/v1.9/_static/img/mascots/scylla-weights.png new file mode 100644 index 00000000000..b070bb022cb Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-weights.png differ diff --git a/v1.9/_static/img/mascots/scylla-window-cleaning.png b/v1.9/_static/img/mascots/scylla-window-cleaning.png new file mode 100644 index 00000000000..6a8b16a6b4e Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-window-cleaning.png differ diff --git a/v1.9/_static/img/mascots/scylla-with-computer-2.png b/v1.9/_static/img/mascots/scylla-with-computer-2.png new file mode 100644 index 00000000000..f3b8b2984f6 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-with-computer-2.png differ diff --git a/v1.9/_static/img/mascots/scylla-with-computer.png b/v1.9/_static/img/mascots/scylla-with-computer.png new file mode 100644 index 00000000000..b38a6fbbe04 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-with-computer.png differ diff --git a/v1.9/_static/img/mascots/scylla-with-linux.png b/v1.9/_static/img/mascots/scylla-with-linux.png new file mode 100644 index 00000000000..954bf13bc29 Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-with-linux.png differ diff --git a/v1.9/_static/img/mascots/scylla-writting.png b/v1.9/_static/img/mascots/scylla-writting.png new file mode 100644 index 00000000000..d35a13d380d Binary files /dev/null and b/v1.9/_static/img/mascots/scylla-writting.png differ diff --git a/v1.9/_static/img/menu.svg b/v1.9/_static/img/menu.svg new file mode 100644 index 00000000000..30ea1d901e1 --- /dev/null +++ b/v1.9/_static/img/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/v1.9/_static/js/main.bundle.js b/v1.9/_static/js/main.bundle.js new file mode 100644 index 00000000000..190a41642ef --- /dev/null +++ b/v1.9/_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 previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Contributing to Scylla Operator

              +
              +

              Prerequisites

              +

              To develop on scylla-operator, your environment must have the following:

              +
                +
              1. Go 1.13

                +
                  +
                • Make sure GOPATH is set to GOPATH=$HOME/go.

                • +
                +
              2. +
              3. Kustomize v3.1.0

              4. +
              5. kubebuilder v2.3.1

              6. +
              7. Docker

              8. +
              9. Git client installed

              10. +
              11. Github account

              12. +
              +

              To install all dependencies (Go, kustomize, kubebuilder, dep), simply run:

              +
              ./install-dependencies.sh
              +
              +
              +
              +
              +

              Initial Setup

              +
              +

              Create a Fork

              +

              From your browser navigate to http://github.com/scylladb/scylla-operator and click the “Fork” button.

              +
              +
              +

              Clone Your Fork

              +

              Open a console window and do the following:

              +
              # Create the scylla operator repo path
              +mkdir -p $GOPATH/src/github.com/scylladb
              +
              +# Navigate to the local repo path and clone your fork
              +cd $GOPATH/src/github.com/scylladb
              +
              +# Clone your fork, where <user> is your GitHub account name
              +git clone https://github.com/<user>/scylla-operator.git
              +
              +
              +
              +
              +

              Add Upstream Remote

              +

              First you will need to add the upstream remote to your local git:

              +
              # Add 'upstream' to the list of remotes
              +git remote add upstream https://github.com/scylladb/scylla-operator.git
              +
              +# Verify the remote was added
              +git remote -v
              +
              +
              +

              Now you should have at least origin and upstream remotes. You can also add other remotes to collaborate with other contributors.

              +
              +
              +
              +

              Development

              +

              To add a feature or to make a bug fix, you will need to create a branch in your fork and then submit a pull request (PR) from the branch.

              +
              +

              Building the project

              +

              You can build the project using the Makefile commands:

              +
                +
              • Open the Makefile and change the IMG environment variable to a repository you have access to.

              • +
              • Run make docker-push and wait for the image to be built and uploaded in your repo.

              • +
              +
              +
              +

              Create a Branch

              +

              From a console, create a new branch based on your fork and start working on it:

              +
              # Ensure all your remotes are up to date with the latest
              +git fetch --all
              +
              +# Create a new branch that is based off upstream master.  Give it a simple, but descriptive name.
              +# Generally it will be two to three words separated by dashes and without numbers.
              +git checkout -b feature-name upstream/master
              +
              +
              +

              Now you are ready to make the changes and commit to your branch.

              +
              +
              +

              Updating Your Fork

              +

              During the development lifecycle, you will need to keep up-to-date with the latest upstream master. As others on the team push changes, you will need to rebase your commits on top of the latest. This avoids unnecessary merge commits and keeps the commit history clean.

              +

              Whenever you need to update your local repository, you never want to merge. You always will rebase. Otherwise you will end up with merge commits in the git history. If you have any modified files, you will first have to stash them (git stash save -u "<some description>").

              +
              git fetch --all
              +git rebase upstream/master
              +
              +
              +

              Rebasing is a very powerful feature of Git. You need to understand how it works or else you will risk losing your work. Read about it in the Git documentation, it will be well worth it. In a nutshell, rebasing does the following:

              +
                +
              • “Unwinds” your local commits. Your local commits are removed temporarily from the history.

              • +
              • The latest changes from upstream are added to the history

              • +
              • Your local commits are re-applied one by one

              • +
              • If there are merge conflicts, you will be prompted to fix them before continuing. Read the output closely. It will tell you how to complete the rebase.

              • +
              • When done rebasing, you will see all of your commits in the history.

              • +
              +
              +
              +
              +

              Submitting a Pull Request

              +

              Once you have implemented the feature or bug fix in your branch, you will open a PR to the upstream repo. Before opening the PR ensure you have added unit tests, are passing the integration tests, cleaned your commit history, and have rebased on the latest upstream.

              +

              In order to open a pull request (PR) it is required to be up to date with the latest changes upstream. If other commits are pushed upstream before your PR is merged, you will also need to rebase again before it will be merged.

              +
              +

              Commit History

              +

              To prepare your branch to open a PR, you will need to have the minimal number of logical commits so we can maintain +a clean commit history. Most commonly a PR will include a single commit where all changes are squashed, although +sometimes there will be multiple logical commits.

              +
              # Inspect your commit history to determine if you need to squash commits
              +git log
              +
              +# Rebase the commits and edit, squash, or even reorder them as you determine will keep the history clean.
              +# In this example, the last 5 commits will be opened in the git rebase tool.
              +git rebase -i HEAD~5
              +
              +
              +

              Once your commit history is clean, ensure you have based on the latest upstream before you open the PR.

              +
              +
              +

              Commit messages

              +

              Please make the first line of your commit message a summary of the change that a user (not a developer) of Operator would like to read, +and prefix it with the most relevant directory of the change followed by a colon. +The changelog gets made by looking at just these first lines so make it good!

              +

              If you have more to say about the commit, then enter a blank line and carry on the description. +Remember to say why the change was needed - the commit itself shows what was changed.

              +

              Writing more is better than less. Comparing the behaviour before the change to that after the change is very useful. +Imagine you are writing to yourself in 12 months time when you’ve forgotten everything about what you just did, and you need to get up to speed quickly.

              +

              If the change fixes an issue then write Fixes #1234 in the commit message. +This can be on the subject line if it will fit. If you don’t want to close the associated issue just put #1234 and the change will get linked into the issue.

              +

              Here is an example of a short commit message:

              +
              sidecar: log on reconcile loop - fixes #1234
              +
              +
              +

              And here is an example of a longer one:

              +
              
              +api: now supports host networking (#1234)
              +
              +The operator CRD now has a "network" property that can be used to
              +select host networking as well as setting the apropriate DNS policy.
              +
              +Fixes #1234
              +
              +
              +
              +
              +

              Submitting

              +

              Go to the Scylla Operator github to open the PR. If you have pushed recently, you should see an obvious link to open the PR. If you have not pushed recently, go to the Pull Request tab and select your fork and branch for the PR.

              +

              After the PR is open, you can make changes simply by pushing new commits. Your PR will track the changes in your fork and update automatically.

              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/eks.html b/v1.9/eks.html new file mode 100644 index 00000000000..20e8607dd6b --- /dev/null +++ b/v1.9/eks.html @@ -0,0 +1,714 @@ + + + + + + + + + + + + + Deploying Scylla on EKS | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Deploying Scylla on EKS

              +

              This guide is focused on deploying Scylla on EKS with improved performance. +Performance tricks used by the script won’t work with different machine tiers. +It sets up the kubelets on EKS nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

              +

              Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

              +
              +

              TL;DR;

              +

              If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

              +
              # Edit according to your preference
              +EKS_REGION=us-east-1
              +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
              +
              +# From inside the examples/eks folder
              +cd examples/eks
              +./eks.sh -z "$EKS_ZONES" -r "$EKS_REGION"
              +
              +
              +

              After you deploy, see how you can benchmark your cluster with cassandra-stress.

              +
              +
              +

              Walkthrough

              +
              +

              EKS Setup

              +
              +

              Configure environment variables

              +

              First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

              +
              EKS_REGION=us-east-1
              +EKS_ZONES=us-east-1a,us-east-1b,us-east-1c
              +CLUSTER_NAME=scylla-demo
              +
              +
              +
              +
              +

              Creating an EKS cluster

              +

              For this guide, we’ll create an EKS cluster with the following:

              +
                +
              • A NodeGroup of 3 i3-2xlarge Nodes, where the Scylla Pods will be deployed. These nodes will only accept pods having scylla-clusters toleration.

              • +
              +
                - name: scylla-pool
              +    instanceType: i3.2xlarge
              +    desiredCapacity: 3
              +    labels:
              +      pool: "scylla-pool"
              +    taints:
              +      role: "scylla-clusters:NoSchedule"
              +    ssh:
              +      allow: true
              +    kubeletExtraConfig:
              +      cpuManagerPolicy: static
              +
              +
              +
                +
              • A NodeGroup of 4 c4.2xlarge Nodes to deploy cassandra-stress later on. These nodes will only accept pods having cassandra-stress toleration.

              • +
              +
                - name: cassandra-stress-pool
              +    instanceType: c4.2xlarge
              +    desiredCapacity: 4
              +    labels:
              +      pool: "cassandra-stress-pool"
              +    taints:
              +      role: "cassandra-stress:NoSchedule"
              +    ssh:
              +      allow: true
              +
              +
              +
                +
              • A NodeGroup of 1 i3.large Node, where the monitoring stack and operator will be deployed.

              • +
              +
                - name: monitoring-pool
              +    instanceType: i3.large
              +    desiredCapacity: 1
              +    labels:
              +      pool: "monitoring-pool"
              +    ssh:
              +      allow: true
              +
              +
              +
              +
              +
              +

              Installing Required Tools

              +
              +

              Installing script third party dependencies

              +

              Script requires several dependencies:

              +
                +
              • Helm - See: https://docs.helm.sh/using_helm/#installing-helm

              • +
              • eksctl - See: https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html

              • +
              • kubectl - See: https://kubernetes.io/docs/tasks/tools/install-kubectl/

              • +
              +
              +
              +

              Install the local provisioner

              +

              We deploy the local volume provisioner, which will discover their mount points and make them available as PersistentVolumes.

              +
              helm install local-provisioner examples/common/provisioner
              +
              +
              +
              +
              +

              Deploy tuning DaemonSet

              +

              Deploy tuning DaemonSet, this will configure your disks and apply several optimizations

              +
              kubectl apply -f node-setup-daemonset.yaml
              +
              +
              +
              +
              +
              +

              Installing the Scylla Operator and Scylla

              +

              Now you can follow the generic guide to launch your Scylla cluster in a highly performant environment.

              +
              +

              Accessing the database

              +

              Instructions on how to access the database can also be found in the generic guide.

              +
              +
              +
              +

              Deleting an EKS cluster

              +

              Once you are done with your experiments delete your cluster using the following command:

              +
              eksctl delete cluster "${CLUSTER_NAME}"
              +
              +
              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/generic.html b/v1.9/generic.html new file mode 100644 index 00000000000..f16424edead --- /dev/null +++ b/v1.9/generic.html @@ -0,0 +1,937 @@ + + + + + + + + + + + + + Deploying Scylla on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Deploying Scylla on a Kubernetes Cluster

              +

              This is a guide to deploy a Scylla Cluster in a generic Kubernetes environment, meaning that Scylla will not be deployed with the ideal performance. +Scylla performs the best when it has fast disks and direct access to the cpu. +This requires some extra setup, which is platform-specific. +For specific configuration and setup, check for details about your particular environment:

              + +
              +

              Prerequisites

              + +
              +
              +

              Running locally

              +

              Running kubernetes locally is a daunting and error prone task. +Fortunately there are ways to make life easier and Minikube makes it a breeze.

              +

              We need to give minikube a little bit more resources than default so start minikube like this:

              +
              minikube start --cpus=6
              +
              +
              +

              Then make kubectl aware of this local installation like this:

              +
              eval $(minikube docker-env)
              +
              +
              +
              +
              +

              Download Scylla Operator

              +

              In this guide you will be using the examples and manifests from Scylla Operator repository, so start off by cloning it to your local machine.

              +
              git clone git@github.com:scylladb/scylla-operator.git
              +cd scylla-operator
              +
              +
              +
              +
              +

              Deploy Cert Manager

              +

              First deploy Cert Manager, you can either follow upsteam instructions or use following command:

              +
              kubectl apply -f examples/common/cert-manager.yaml
              +
              +
              +

              This will install Cert Manager to provision a self-signed certificate.

              +

              Once it’s deployed, wait until Cert Manager is ready:

              +
              kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io
              +kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook
              +
              +
              +
              +
              +

              Deploy Scylla Operator

              +

              Deploy the Scylla Operator using the following commands:

              +
              kubectl apply -f examples/common/operator.yaml
              +
              +
              +

              This will install the operator in namespace scylla-operator. +Wait until it’s ready:

              +
              kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
              +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
              +
              +
              +

              If you want to check the logs of the operator you can do so with:

              +
              kubectl -n scylla-operator logs deployment.apps/scylla-operator
              +
              +
              +
              +
              +

              Create and Initialize a Scylla Cluster

              +

              Now that the operator is running, we can create an instance of a Scylla cluster by creating an instance of the clusters.scylla.scylladb.com resource. +Some of that resource’s values are configurable, so feel free to browse cluster.yaml and tweak the settings to your liking. +Full details for all the configuration options can be found in the Scylla Cluster CRD documentation.

              +

              When you are ready to create a Scylla cluster, simply run:

              +
              kubectl create -f examples/generic/cluster.yaml
              +
              +
              +

              We can verify that a Kubernetes object has been created that represents our new Scylla cluster with the command below. +This is important because it shows that has successfully extended Kubernetes to make Scylla clusters a first class citizen in the Kubernetes cloud-native environment.

              +
              kubectl -n scylla get ScyllaCluster
              +
              +
              +

              Checking the pods that are created is as easy as:

              +
              kubectl -n scylla get pods
              +
              +
              +

              The output should be something like:

              +
              NAME                                    READY   STATUS    RESTARTS   AGE
              +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          9m49s
              +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          7m43s
              +simple-cluster-us-east-1-us-east-1a-2   2/2     Running   0          6m46s
              +
              +
              +

              It is important to note that the operator creates these instances according to a pattern. +This pattern is as follows: CLUSTER_NAME-DATACENTER_NAME-RACK_NAME-INSTANCE_NUMBER as specified in cluster.yaml.

              +

              In the above example we have the following properties:

              +
                +
              • CLUSTER_NAME: simple-cluster

              • +
              • DATACENTER_NAME: us-east-1

              • +
              • RACK_NAME: us-east-1a

              • +
              • INSTANCE_NUMBER: An automatically generated number attached to the pod name.

              • +
              +

              We picked the names to resemble something you can find in a cloud service but this is inconsequential, they can be set to anything you want.

              +

              To check if all the desired members are running, you should see the same number of entries from the following command as the number of members that was specified in cluster.yaml:

              +
              kubectl -n scylla get pod -l app=scylla
              +
              +
              +

              You can also track the state of a Scylla cluster from its status. To check the current status of a Cluster, run:

              +
              kubectl -n scylla describe ScyllaCluster simple-cluster
              +
              +
              +

              Checking the logs of the running scylla instances can be done like this:

              +
              kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0 scylla
              +
              +
              +
              +

              Configure host networking

              +

              To squeeze the most out of your deployment it is sometimes necessary to employ host networking. +To enable this the CRD allows for specifying a network parameter as such:

              +
              version: 4.0.0
              +  agentVersion: 2.0.2
              +  cpuset: true
              +  network:
              +    hostNetworking: true
              +
              +
              +

              This will result in hosts network to be used for the Scylla Stateful Set deployment.

              +
              +
              +

              Configure container kernel parameters

              +

              Sometimes it is necessary to run the container with different kernel parameters. +In order to support this, the Scylla Operator defines a cluster property sysctls that is a list of the desired key-value pairs to set.

              +

              For example: To increase the number events available for asynchronous IO processing in the Linux kernel to N set sysctls tofs.aio-max-nr=N.

              +
              spec:
              +  sysctls:
              +  - "fs.aio-max-nr=2097152"
              +
              +
              +
              +
              +

              Deploying Alternator

              +

              The operator is also capable of deploying Alternator instead of the regular Scylla. +This requires a small change in the cluster definition. +Change the cluster.yaml file from this:

              +
              spec:
              +  version: 4.0.0
              +  agentVersion: 2.0.2
              +  developerMode: true
              +  datacenter:
              +    name: us-east-1
              +
              +
              +

              to this:

              +
              spec:
              +  version: 4.0.0
              +  alternator:
              +    port: 8000
              +    writeIsolation: only_rmw_uses_lwt
              +  agentVersion: 2.0.2
              +  developerMode: true
              +  datacenter:
              +    name: us-east-1
              +
              +
              +

              You can specify whichever port you want.

              +

              You must provide desired write isolation, supported values are: “always”, “forbid_rmw”, “only_rmw_uses_lwt”. +Difference between those isolation levels can be found in Scylla Alternator documentation.

              +

              Once this is done the regular CQL ports will no longer be available, the cluster is a pure Alienator cluster.

              +
              +
              +
              +

              Accessing the Database

              +
                +
              • From kubectl:

              • +
              +

              To get a cqlsh shell in your new Cluster:

              +
              kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- cqlsh
              +> DESCRIBE KEYSPACES;
              +
              +
              +
                +
              • From inside a Pod:

              • +
              +

              When you create a new Cluster, automatically creates a Service for the clients to use in order to access the Cluster. +The service’s name follows the convention <cluster-name>-client. +You can see this Service in your cluster by running:

              +
              kubectl -n scylla describe service simple-cluster-client
              +
              +
              +

              Pods running inside the Kubernetes cluster can use this Service to connect to Scylla. +Here’s an example using the Python Driver:

              +
              from cassandra.cluster import Cluster
              +
              +cluster = Cluster(['simple-cluster-client.scylla.svc'])
              +session = cluster.connect()
              +
              +
              +

              If you are running the Alternator you can access the API on the port you specified using plain http.

              +
              +
              +

              Configure Scylla

              +

              The operator can take a ConfigMap and apply it to the scylla.yaml configuration file. +This is done by adding a ConfigMap to Kubernetes and refering to this in the Rack specification. +The ConfigMap is just a file called scylla.yaml that has the properties you want to change in it. +The operator will take the default properties for the rest of the configuration.

              +
                +
              • Create a ConfigMap the default name that the operator uses is scylla-config:

              • +
              +
              kubectl create configmap scylla-config -n scylla --from-file=/path/to/scylla.yaml
              +
              +
              +
                +
              • Wait for the mount to propagate and then restart the cluster:

              • +
              +
              kubectl rollout restart -n scylla statefulset/simple-cluster-us-east-1-us-east-1a
              +
              +
              +
                +
              • The new config should be applied automatically by the operator, check the logs to be sure.

              • +
              +

              Configuring cassandra-rackdc.properties is done by adding the file to the same mount as scylla.yaml.

              +
              kubectl create configmap scylla-config -n scylla --from-file=/tmp/scylla.yaml --from-file=/tmp/cassandra-rackdc.properties -o yaml --dry-run | kubectl replace -f -
              +
              +
              +

              The operator will then apply the overridable properties prefer_local and dc_suffix if they are available in the provided mounted file.

              +
              +
              +

              Configure Scylla Manager Agent

              +

              The operator creates a second container for each scylla instance that runs Scylla Manager Agent. +This container serves as a sidecar and it’s the main endpoint for interacting with Scylla API. +The Scylla Manager Agent can be configured with various things such as the security token used to allow access to Scylla API and storage providers for backups.

              +

              To configure the agent you just create a new secret called scylla-agent-config-secret and populate it with the contents in the scylla-manager-agent.yaml file like this:

              +
              kubectl create secret -n scylla generic scylla-agent-config-secret --from-file scylla-manager-agent.yaml
              +
              +
              +

              See Scylla Manager Agent configuration for a complete reference of the Scylla Manager agent config file.

              +
              +

              Scylla Manager Agent auth token

              +

              Operator provisions Agent auth token by copying value from user provided config secret or auto generates it if it’s empty. +To check which value is being used, decode content of <cluster-name>-auth-token secret. +To change it simply remove the secret. Operator will create a new one. To pick up the change in the cluster, initiate a rolling restart.

              +
              +
              +
              +

              Set up monitoring

              +

              To set up monitoring using Prometheus and Grafana follow this guide.

              +
              +
              +

              Scale Up

              +

              The operator supports scale up of a rack as well as addition of new racks. To make the changes, you can use:

              +
              kubectl -n scylla edit ScyllaCluster simple-cluster
              +
              +
              +
                +
              • To scale up a rack, change the Spec.Members field of the rack to the desired value.

              • +
              • To add a new rack, append the racks list with a new rack. Remember to choose a different rack name for the new rack.

              • +
              • After editing and saving the yaml, check your cluster’s Status and Events for information on what’s happening:

              • +
              +
              kubectl -n scylla describe ScyllaCluster simple-cluster
              +
              +
              +
              +
              +

              Benchmark with cassandra-stress

              +

              After deploying our cluster along with the monitoring, we can benchmark it using cassandra-stress and see its performance in Grafana. We have a mini cli that generates Kubernetes Jobs that run cassandra-stress against a cluster.

              +
              +

              Because cassandra-stress doesn’t scale well to multiple cores, we use multiple jobs with a small core count for each

              +
              +
              # Run a benchmark with 10 jobs, with 6 cpus and 50.000.000 operations each.
              +# Each Job will throttle throughput to 30.000 ops/sec for a total of 300.000 ops/sec.
              +hack/cass-stress-gen.py --num-jobs=10 --cpu=6 --memory=20G --ops=50000000 --limit=30000
              +kubectl apply -f scripts/cassandra-stress.yaml
              +
              +
              +

              Make sure you set the proper arguments in case you have altered things such as name or namespace.

              +
              ./hack/cass-stress-gen.py -h
              +usage: cass-stress-gen.py [-h] [--num-jobs NUM_JOBS] [--name NAME] [--namespace NAMESPACE] [--scylla-version SCYLLA_VERSION] [--host HOST] [--cpu CPU] [--memory MEMORY] [--ops OPS] [--threads THREADS] [--limit LIMIT]
              +                          [--connections-per-host CONNECTIONS_PER_HOST] [--print-to-stdout] [--nodeselector NODESELECTOR]
              +
              +Generate cassandra-stress job templates for Kubernetes.
              +
              +optional arguments:
              +  -h, --help            show this help message and exit
              +  --num-jobs NUM_JOBS   number of Kubernetes jobs to generate - defaults to 1
              +  --name NAME           name of the generated yaml file - defaults to cassandra-stress
              +  --namespace NAMESPACE
              +                        namespace of the cassandra-stress jobs - defaults to "default"
              +  --scylla-version SCYLLA_VERSION
              +                        version of scylla server to use for cassandra-stress - defaults to 4.0.0
              +  --host HOST           ip or dns name of host to connect to - defaults to scylla-cluster-client.scylla.svc
              +  --cpu CPU             number of cpus that will be used for each job - defaults to 1
              +  --memory MEMORY       memory that will be used for each job in GB, ie 2G - defaults to 2G * cpu
              +  --ops OPS             number of operations for each job - defaults to 10000000
              +  --threads THREADS     number of threads used for each job - defaults to 50 * cpu
              +  --limit LIMIT         rate limit for each job - defaults to no rate-limiting
              +  --connections-per-host CONNECTIONS_PER_HOST
              +                        number of connections per host - defaults to number of cpus
              +  --print-to-stdout     print to stdout instead of writing to a file
              +  --nodeselector NODESELECTOR
              +                        nodeselector limits cassandra-stress pods to certain nodes. Use as a label selector, eg. --nodeselector role=scylla
              +
              +
              +

              While the benchmark is running, open up Grafana and take a look at the monitoring metrics.

              +

              After the Jobs finish, clean them up with:

              +
              kubectl delete -f scripts/cassandra-stress.yaml
              +
              +
              +
              +
              +

              Scale Down

              +

              The operator supports scale down of a rack. To make the changes, you can use:

              +
              kubectl -n scylla edit ScyllaCluster simple-cluster
              +
              +
              +
                +
              • To scale down a rack, change the Spec.Members field of the rack to the desired value.

              • +
              • After editing and saving the yaml, check your cluster’s Status and Events for information on what’s happening:

              • +
              +
              kubectl -n scylla describe ScyllaCluster simple-cluster
              +
              +
              +
              +
              +

              Clean Up

              +

              To clean up all resources associated with this walk-through, you can run the commands below.

              +

              NOTE: this will destroy your database and delete all of its associated data.

              +
              kubectl delete -f examples/generic/cluster.yaml
              +kubectl delete -f examples/common/operator.yaml
              +kubectl delete -f examples/common/cert-manager.yaml
              +
              +
              +
              +
              +

              Troubleshooting

              +

              If the cluster does not come up, the first step would be to examine the operator’s logs:

              +
              kubectl -n scylla-operator logs deployment.apps/scylla-operator
              +
              +
              +

              If everything looks OK in the operator logs, you can also look in the logs for one of the Scylla instances:

              +
              kubectl -n scylla logs simple-cluster-us-east-1-us-east-1a-0
              +
              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/genindex.html b/v1.9/genindex.html new file mode 100644 index 00000000000..126232b233a --- /dev/null +++ b/v1.9/genindex.html @@ -0,0 +1,543 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + + + +
              + + + + + +
              + + +
              + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/gke.html b/v1.9/gke.html new file mode 100644 index 00000000000..d5fa096d83e --- /dev/null +++ b/v1.9/gke.html @@ -0,0 +1,758 @@ + + + + + + + + + + + + + Deploying Scylla on GKE | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Deploying Scylla on GKE

              +

              This guide is focused on deploying Scylla on GKE with maximum performance (without any persistence guarantees). +It sets up the kubelets on GKE nodes to run with static cpu policy and uses local sdd disks in RAID0 for maximum performance.

              +

              Most of the commands used to setup the Scylla cluster are the same for all environments +As such we have tried to keep them separate in the general guide.

              +
              +

              TL;DR;

              +

              If you don’t want to run the commands step-by-step, you can just run a script that will set everything up for you:

              +
              # Edit according to your preference
              +GCP_USER=$(gcloud config list account --format "value(core.account)")
              +GCP_PROJECT=$(gcloud config list project --format "value(core.project)")
              +GCP_ZONE=us-west1-b
              +
              +# From inside the examples/gke folder
              +cd examples/gke
              +./gke.sh -u "$GCP_USER" -p "$GCP_PROJECT" -z "$GCP_ZONE"
              +
              +# Example:
              +# ./gke.sh -u yanniszark@arrikto.com -p gke-demo-226716 -z us-west1-b
              +
              +
              +

              :warning: Make sure to pass a ZONE (ex.: us-west1-b) and not a REGION (ex.: us-west1) or it will deploy nodes in each ZONE available in the region.

              +

              After you deploy, see how you can benchmark your cluster with cassandra-stress.

              +
              +
              +

              Walkthrough

              +
              +

              Google Kubernetes Engine Setup

              +
              +

              Configure environment variables

              +

              First of all, we export all the configuration options as environment variables. +Edit according to your own environment.

              +
              GCP_USER=$( gcloud config list account --format "value(core.account)" )
              +GCP_PROJECT=$( gcloud config list project --format "value(core.project)" )
              +GCP_REGION=us-west1
              +GCP_ZONE=us-west1-b
              +CLUSTER_NAME=scylla-demo
              +CLUSTER_VERSION=$( gcloud container get-server-config --zone ${GCP_ZONE} --format "value(validMasterVersions[0])" )
              +
              +
              +
              +
              +

              Creating a GKE cluster

              +

              First we need to change kubelet CPU Manager policy to static by providing a config file. Create file called systemconfig.yaml with the following content:

              +
              kubeletConfig:
              +  cpuManagerPolicy: static
              +
              +
              +

              Then we’ll create a GKE cluster with the following:

              +
                +
              1. A NodePool of 2 n1-standard-8 Nodes, where the operator and the monitoring stack will be deployed. These are generic Nodes and their free capacity can be used for other purposes.

                +
                gcloud container \
                +clusters create "${CLUSTER_NAME}" \
                +--cluster-version "${CLUSTER_VERSION}" \
                +--node-version "${CLUSTER_VERSION}" \
                +--machine-type "n1-standard-8" \
                +--num-nodes "2" \
                +--disk-type "pd-ssd" --disk-size "20" \
                +--image-type "UBUNTU_CONTAINERD" \
                +--system-config-from-file=systemconfig.yaml \
                +--enable-stackdriver-kubernetes \
                +--no-enable-autoupgrade \
                +--no-enable-autorepair
                +
                +
                +
              2. +
              3. A NodePool of 2 n1-standard-32 Nodes to deploy cassandra-stress later on.

                +
                gcloud container --project "${GCP_PROJECT}" \
                +node-pools create "cassandra-stress-pool" \
                +--cluster "${CLUSTER_NAME}" \
                +--zone "${GCP_ZONE}" \
                +--node-version "${CLUSTER_VERSION}" \
                +--machine-type "n1-standard-32" \
                +--num-nodes "2" \
                +--disk-type "pd-ssd" --disk-size "20" \
                +--node-taints role=cassandra-stress:NoSchedule \
                +--image-type "UBUNTU_CONTAINERD" \
                +--no-enable-autoupgrade \
                +--no-enable-autorepair
                +
                +
                +
              4. +
              5. A NodePool of 4 n1-standard-32 Nodes, where the Scylla Pods will be deployed. Each of these Nodes has 8 local SSDs attached, which are combined into a RAID0 array by using gcloud beta feature ephemeral-storage. It is important to disable autoupgrade and autorepair. Automatic cluster upgrade or node repair has a hard timeout after which it no longer respect PDBs and force deletes the Compute Engine instances, which also deletes all data on the local SSDs. At this point, it’s better to handle upgrades manually, with more control over the process and error handling.

                +
                gcloud beta container \
                +node-pools create "scylla-pool" \
                +--cluster "${CLUSTER_NAME}" \
                +--node-version "${CLUSTER_VERSION}" \
                +--machine-type "n1-standard-32" \
                +--num-nodes "4" \
                +--disk-type "pd-ssd" --disk-size "20" \
                +--ephemeral-storage local-ssd-count="8" \
                +--node-taints role=scylla-clusters:NoSchedule \
                +--node-labels scylla.scylladb.com/gke-ephemeral-storage-local-ssd=true \
                +--image-type "UBUNTU_CONTAINERD" \
                +--no-enable-autoupgrade \
                +--no-enable-autorepair
                +
                +
                +
              6. +
              +
              +
              +

              Setting Yourself as cluster-admin

              +
              +

              (By default GKE doesn’t give you the necessary RBAC permissions)

              +
              +

              Get the credentials for your new cluster

              +
              gcloud container clusters get-credentials "${CLUSTER_NAME}" --zone="${GCP_ZONE}"
              +
              +
              +

              Create a ClusterRoleBinding for your user. +In order for this to work you need to have at least permission container.clusterRoleBindings.create. +The easiest way to obtain this permission is to enable the Kubernetes Engine Admin role for your user in the GCP IAM web interface.

              +
              kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user "${GCP_USER}"
              +
              +
              +
              +
              +
              +

              Installing Required Tools

              +
              +

              Installing Helm

              +

              If you don’t have Helm installed, Go to the helm docs to get the binary for your distro.

              +
              +
              +

              Install xfs-formatter DaemonSet

              +

              To run Scylla, it is necessary to convert ephemeral storage’s filesystem to xfs. Deploy the xfs-formatter DaemonSet to have it taken care of. +Unfortunately, GKE is only able to provision the ephemeral storage with ext4 filesystem while Scylla requires xfs filesystem. Deploying the xfs-format DaemonSet will format the storage as xfs and prevent GKE from reformatting it back to ext4.

              +

              Note that despite our best efforts, this solution is only a workaround. Its robustness depends on GKE’s disk formatting logic remaining unchanged, for which there is no guarantee.

              +
              kubectl apply -f examples/gke/xfs-formatter-daemonset.yaml
              +
              +
              +
              +
              +

              Install the local provisioner

              +

              Afterwards, deploy the local volume provisioner, which will discover the RAID0 arrays’ mount points and make them available as PersistentVolumes.

              +
              helm install local-provisioner examples/common/provisioner
              +
              +
              +
              +
              +
              +

              Deploy Scylla cluster

              +

              In order for the example to work you need to modify the cluster definition in the following way:

              +
              sed -i "s/<gcp_region>/${GCP_REGION}/g;s/<gcp_zone>/${GCP_ZONE}/g" examples/gke/cluster.yaml
              +
              +
              +

              This will inject your region and zone into the cluster definition so that it matches the kubernetes cluster you just created.

              +
              +
              +

              Installing the Scylla Operator and Scylla

              +

              Now you can follow the generic guide to install the operator and launch your Scylla cluster in a highly performant environment.

              +
              +

              Accessing the database

              +

              Instructions on how to access the database can also be found in the generic guide.

              +
              +
              +
              +

              Deleting a GKE cluster

              +

              Once you are done with your experiments delete your cluster using the following command:

              +
              gcloud container --project "${GCP_PROJECT}" clusters delete --zone "${GCP_ZONE}" "${CLUSTER_NAME}"
              +
              +
              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/helm.html b/v1.9/helm.html new file mode 100644 index 00000000000..8f8dbe10050 --- /dev/null +++ b/v1.9/helm.html @@ -0,0 +1,910 @@ + + + + + + + + + + + + + Deploying Scylla stack using Helm Charts | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Deploying Scylla stack using Helm Charts

              +

              In this example we will install Scylla stack on Kubernetes. This includes the following components:

              +
                +
              • Scylla Operator

              • +
              • Scylla Manager

              • +
              • Scylla

              • +
              +

              We will use Minikube K8s cluster, but this could be any K8s cluster supported by the Scylla Operator.

              +
              +

              Prerequisites

              +
                +
              • Kubernetes 1.16+

              • +
              • Helm 3+

              • +
              +
              +
              +

              TL;DR

              +
              helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
              +helm repo update
              +kubectl apply -f examples/common/cert-manager.yaml 
              +helm install scylla-operator scylla/scylla-operator --create-namespace --namespace scylla-operator
              +helm install scylla-manager scylla/scylla-manager --create-namespace --namespace scylla-manager
              +helm install scylla scylla/scylla --create-namespace --namespace scylla
              +
              +
              +
              +
              +

              Deploy Cert Manager

              +

              This step is optional if you want to use your own certificate. +If you don’t have one, make sure to not disable autogeneration using Scylla Operator Helm Chart.

              +

              First deploy Cert Manager, you can either follow upsteam instructions or use following command:

              +
              kubectl apply -f examples/common/cert-manager.yaml
              +
              +
              +

              Once it’s deployed, wait until all Cert Manager pods will enter into Running state:

              +
              kubectl wait -n cert-manager --for=condition=ready pod -l app=cert-manager --timeout=60s
              +
              +
              +
              +
              +

              Helm Chart repository

              +

              To install Scylla Helm Chart repository execute the following commands:

              +
              helm repo add scylla https://scylla-operator-charts.storage.googleapis.com/stable
              +helm repo update
              +
              +
              +

              Then you can search through repository, it should contain at least three Helm charts:

              +
              helm search repo scylla
              +NAME                   CHART VERSION   APP VERSION     DESCRIPTION                                       
              +scylla/scylla          1.0.1           v1.0.1          Scylla is a close-to-the-hardware rewrite of Ca...
              +scylla/scylla-manager  1.0.1           v1.0.1          Scylla Manager automates database operations.     
              +scylla/scylla-operator 1.0.1           v1.0.1          Scylla Operator is a Kubernetes Operator for ma...
              +
              +
              +

              All these charts should be installable without any need of customizing (defaults are provided). +Although Helm is used for this particular reason, so lets customize them a bit.

              +
              +
              +

              Scylla Operator Chart

              +

              This chart is very simple, most interesting customizable fields are image, resources and webhook. +All others can be looked up in Chart source in Scylla Operator repository.

              +
              +

              image

              +

              Image allows to define which Scylla Operator image will be used. By default it downloads the image from main +Docker Hub repository, using version defined in Helm Chart. +You can also change pullPolicy if default one does not +fullfill your needs. In Kubernetes documentation you +can read more about different pull policies.

              +

              Image URL will be composed based on these fields in follwing pattern: +repository/scylla-operator:tag

              +
              image:
              +  repository: scylladb
              +  pullPolicy: IfNotPresent
              +  tag: ""
              +
              +
              +
              +
              +

              resources

              +

              You can customize how much resources will be allocated for Operator pods via resource field:

              +
              resources:
              +  limits:
              +    cpu: 100m
              +    memory: 128Mi
              +  requests:
              +    cpu: 100m
              +    memory: 32Mi
              +
              +
              +

              To read more about resource specification, follow Kubernetes documentation.

              +
              +
              +

              webhook

              +

              Webhook field allows to decide whether you want to use autogenerated self-signed certificate using Cert Manager or +whether you want to provide your own certificate.

              +

              createSelfSignedCertificate specifies whether a self-signed certificate should be created using Cert Manager +certificateSecretName: name of a secret containing custom certificate.

              +
              webhook:
              +  createSelfSignedCertificate: true
              +  certificateSecretName: ""
              +
              +
              +
              +
              +

              Customization

              +

              You can customize all these fields and others by providing file containing desired values. +Content of this file will overwrite default values.

              +

              You can find an example in Scylla Operator repository under examples/helm/values.operator.yaml

              +
              +
              +

              Installation

              +

              To deploy Scylla Operator using customized values file execute the following:

              +
              helm install scylla-operator scylla/scylla-operator --values examples/helm/values.operator.yaml --create-namespace --namespace scylla-operator
              +
              +
              +
              +
              +
              +

              Scylla Helm Chart

              +

              Scylla Chart allows to customize and deploy Scylla cluster. +By default Scylla Helm charts deploys working Scylla cluster, but of course we can customize it.

              +
              +

              Customization

              +

              Versions of images used in the cluster can be set via scyllaImage and agentImage

              +
              scyllaImage:
              +  repository: scylladb/scylla
              +  tag: 4.3.0
              +
              +agentImage:
              +  repository: scylladb/scylla-manager-agent
              +  tag: 2.2.1
              +
              +
              +

              A minimal Scylla cluster can be expressed as:

              +
              datacenter: us-east-1
              +racks:
              +- name: us-east-1b
              +  members: 2
              +  storage:
              +    capacity: 5G
              +  resources:
              +    limits:
              +      cpu: 1
              +      memory: 1Gi
              +    requests:
              +      cpu: 1
              +      memory: 1Gi
              +
              +
              +

              Above cluster will use 4.3.0 Scylla, 2.2.1 Scylla Manager Agent sidecar and will have a single rack having 2 nodes. +Each node will have a single CPU and 1 GiB of memory.

              +

              For other customizable fields, please refer to ScyllaCluster CRD definition. +CRD Rack Spec and Helm Chart Rack should have the same fields.

              +
              +
              +

              Installation

              +

              To deploy Scylla cluster using customzied values file execute the following command:

              +
              helm install scylla scylla/scylla --values examples/helm/values.cluster.yaml --create-namespace --namespace scylla
              +
              +
              +

              Scylla Operator will provision this cluster on your K8s environment.

              +
              +
              +
              +

              Scylla Manager Helm Chart

              +

              Scylla Manager Chart allows to customize and deploy Scylla Manager in K8s environment. +Scylla Manager consist of two applications (Scylla Manager itself and Scylla Manager Controller) and additional Scylla cluster.

              +

              To read more about Scylla Manager see Manager guide.

              +
              +

              Scylla Manager

              +

              To set version of used Scylla Manager you can use image field:

              +
              image:
              +  repository: scylladb
              +  pullPolicy: IfNotPresent
              +  tag: 2.2.1
              +
              +
              +

              To control how many resources are allocated for Scylla Manager use resource field:

              +
              resources:
              +  limits:
              +    cpu: 500m
              +    memory: 500Mi
              +  requests:
              +    cpu: 500m
              +    memory: 500Mi
              +
              +
              +
              +
              +

              Scylla Manager Controller

              +

              Similarly Scylla Manager Controller image can be customized:

              +
              controllerImage:
              +  repository: scylladb
              +  pullPolicy: IfNotPresent
              +  tag: ""
              +
              +
              +

              And allocated resources:

              +
              controllerResources:
              +  limits:
              +    cpu: 100m
              +    memory: 30Mi
              +  requests:
              +    cpu: 100m
              +    memory: 20Mi
              +
              +
              +
              +
              +

              Scylla

              +

              To customize internal Scylla instance dedicated to Scylla Manager, see guide above customizing Scylla Helm Chart. +It’s definition should land as a scylla field.

              +
              +
              +

              Customization

              +

              All others customizable fields can be looked up in Chart source in Scylla Operator repository.

              +
              +
              +

              Installation

              +

              To deploy Scylla Manager using customized values file execute the following command:

              +
              helm install scylla-manager scylla/scylla-manager --values examples/helm/values.manager.yaml --create-namespace --namespace scylla-manager
              +
              +
              +
              +
              +
              +

              Results

              +

              Scylla need some time to bootstrap all nodes, but after some time you should be ready to roll. It was simple isn’t it? +You can validate if everything was set up correctly by looking at the all resources created in used namespaces.

              +

              Scylla Operator:

              +
              $ kubectl -n scylla-operator get all
              +
              +NAME                                   READY   STATUS    RESTARTS   AGE
              +pod/scylla-operator-5dbcb54f5c-vjm4m   1/1     Running   0          51s
              +pod/scylla-operator-5dbcb54f5c-wfjbw   1/1     Running   0          51s
              +
              +NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
              +service/scylla-operator-webhook   ClusterIP   10.105.207.130   <none>        443/TCP   51s
              +
              +NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
              +deployment.apps/scylla-operator   2/2     2            2           51s
              +
              +NAME                                         DESIRED   CURRENT   READY   AGE
              +replicaset.apps/scylla-operator-5dbcb54f5c   2         2         2       51s
              +
              +
              +

              Operator is running!

              +

              Scylla Manager:

              +
              $ kubectl -n scylla-manager get all 
              +
              +NAME                                             READY   STATUS    RESTARTS   AGE
              +pod/scylla-manager-669db64dd-bcm4v               1/1     Running   0          89s
              +pod/scylla-manager-controller-844ccc56c4-drbth   1/1     Running   0          89s
              +pod/scylla-manager-controller-844ccc56c4-rhwqx   1/1     Running   0          89s
              +
              +NAME                            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
              +service/scylla-manager          ClusterIP   10.105.231.53   <none>        80/TCP,5090/TCP     89s
              +service/scylla-manager-client   ClusterIP   None            <none>        9180/TCP,5090/TCP   89s
              +
              +NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
              +deployment.apps/scylla-manager              1/1     1            1           89s
              +deployment.apps/scylla-manager-controller   2/2     2            2           89s
              +
              +NAME                                                   DESIRED   CURRENT   READY   AGE
              +replicaset.apps/scylla-manager-669db64dd               1         1         1       89s
              +replicaset.apps/scylla-manager-controller-844ccc56c4   2         2         2       89s
              +
              +
              +

              Good to go, ready to serve!

              +

              Scylla itself:

              +
              $ kubectl -n scylla get all        
              +
              +NAME                                READY   STATUS    RESTARTS   AGE
              +pod/scylla-us-east-1-us-east-1b-0   2/2     Running   0          5m58s
              +pod/scylla-us-east-1-us-east-1b-1   2/2     Running   0          4m29s
              +
              +NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
              +service/scylla-client                   ClusterIP   None           <none>        9180/TCP,5090/TCP                                                 5m59s
              +service/scylla-us-east-1-us-east-1b-0   ClusterIP   10.43.149.92   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   5m58s
              +service/scylla-us-east-1-us-east-1b-1   ClusterIP   10.43.49.0     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   4m29s
              +
              +NAME                                           READY   AGE
              +statefulset.apps/scylla-us-east-1-us-east-1b   2/2     5m59s
              +
              +
              +

              Two running nodes, exactly what we were asking for.

              +
              +
              +

              Monitoring

              +

              To spin up a Prometheus monitoring refer to monitoring guide.

              +

              Helm charts can create ServiceMonitors needed to observe Scylla Managger and Scylla. +Both of these Helm Charts allows to specify whether you want to create a ServiceMonitor:

              +
              serviceMonitor:
              +  create: false
              +
              +
              +

              Change create to true and update your current deployment using:

              +
              helm upgrade --install scylla --namespace scylla scylla/scylla -f examples/helm/values.cluster.yaml
              +
              +
              +

              Helm should notice the difference, install the ServiceMonitor, and then Prometheous will be able to scrape metrics.

              +
              +
              +

              Cleanup

              +

              To remove these applications you can simply uninstall them using Helm CLI:

              +
              helm uninstall scylla -n scylla
              +helm uninstall scylla-manager -n scylla-manager
              +helm uninstall scylla-operator -n scylla-operator
              +
              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/index.html b/v1.9/index.html new file mode 100644 index 00000000000..c5c402b493d --- /dev/null +++ b/v1.9/index.html @@ -0,0 +1,589 @@ + + + + + + + + + + + + + Scylla Operator Documentation | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Scylla Operator Documentation

              +
              +
              +

              Scylla Operator is an open source project which helps users of Scylla Open Source and Scylla Enterprise run Scylla on Kubernetes (K8s) +The Scylla operator manages Scylla clusters deployed to Kubernetes and automates tasks related to operating a Scylla cluster, like installation, out and downscale, rolling upgrades.

              +_images/logo.png +

              For the latest status of the project, and reports issue, see the Github Project. Also check out the K8s Operator lesson on Scylla University.

              +

              scylla-operator is a Kubernetes Operator for managing Scylla clusters.

              +

              Currently it supports:

              +
                +
              • Deploying multi-zone clusters

              • +
              • Scaling up or adding new racks

              • +
              • Scaling down

              • +
              • Monitoring with Prometheus and Grafana

              • +
              • Integration with Scylla Manager

              • +
              • Dead node replacement

              • +
              • Version Upgrade

              • +
              • Backup

              • +
              • Repairs

              • +
              • Autohealing

              • +
              • Monitoring with Prometheus and Grafana

              • +
              +

              Choose a topic to begin:

              + +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/known_issues.html b/v1.9/known_issues.html new file mode 100644 index 00000000000..55f9fd6ab65 --- /dev/null +++ b/v1.9/known_issues.html @@ -0,0 +1,586 @@ + + + + + + + + + + + + + Known issues | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Known issues

              +
              +

              Scylla Manager does not boot up on Minikube

              +

              If your Scylla Manager is failing to apply 8th migration (008_*), then apply fix for TRUNCATE queries.

              +
              +
              +

              TRUNCATE queries does not work on Minikube

              +

              The TRUNCATE queries requires hairpinning to be enabled. On minikube this is disabled by default.

              +

              To fix it execute the following command:

              +
              minikube ssh sudo ip link set docker0 promisc on
              +
              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/manager.html b/v1.9/manager.html new file mode 100644 index 00000000000..98127b37601 --- /dev/null +++ b/v1.9/manager.html @@ -0,0 +1,797 @@ + + + + + + + + + + + + + Deploying Scylla Manager on a Kubernetes Cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Deploying Scylla Manager on a Kubernetes Cluster

              +

              Scylla Manager is a product for database operations automation, +it can schedule tasks such as repairs and backups. +Scylla Manager can manage multiple Scylla clusters and run cluster-wide tasks +in a controlled and predictable way.

              +

              Scylla Manager is available for Scylla Enterprise customers and Scylla Open Source users. +With Scylla Open Source, Scylla Manager is limited to 5 nodes. +See the Scylla Manager Proprietary Software License Agreement for details.

              +
              +

              Prerequisites

              + +
              +
              +

              Architecture

              +

              Scylla Manager in K8s consist of:

              +
                +
              • Dedicated Scylla Cluster

                +

                Scylla Manager persists its state to a Scylla cluster. +Additional small single node cluster is spawned in the Manager namespace.

                +
              • +
              • Scylla Manager Controller

                +

                Main mission of Controller is to watch changes of Scylla Clusters, and synchronize three states.

                +
                  +
                1. What user wants - task definition in CRD.

                2. +
                3. What Controller registered - Task name to Task ID mapping - CRD status.

                4. +
                5. Scylla Manager task listing - internal state of Scylla Manager.

                6. +
                +

                When Scylla Cluster CRD is being deployed Controller will register it in Scylla Manager once cluster reaches desired node count. +Once Cluster is fully up and running it will schedule all tasks defined in Cluster CRD. +Controller also supports task updates and unscheduling.

                +
              • +
              • Scylla Manager

                +

                Regular Scylla Manager, the same used in cloud and bare metal deployments.

                +
              • +
              +
              +
              +

              Deploy Scylla Manager

              +

              Deploy the Scylla Manager using the following commands:

              +
              kubectl apply -f examples/common/manager.yaml
              +
              +
              +

              This will install the Scylla Manager in the scylla-manager namespace. +You can check if the Scylla Manager is up and running with:

              +
              kubectl -n scylla-manager get pods
              +NAME                                               READY   STATUS    RESTARTS   AGE
              +scylla-manager-cluster-manager-dc-manager-rack-0   2/2     Running   0          37m
              +scylla-manager-controller-0                        1/1     Running   0          28m
              +scylla-manager-scylla-manager-7bd9f968b9-w25jw     1/1     Running   0          37m
              +
              +
              +

              As you can see there are three pods:

              +
                +
              • scylla-manager-cluster-manager-dc-manager-rack-0 - is a single node Scylla cluster.

              • +
              • scylla-manager-controller-0 - Scylla Manager Controller.

              • +
              • scylla-manager-scylla-manager-7bd9f968b9-w25jw - Scylla Manager.

              • +
              +

              To see if Scylla Manager is fully up and running we can check their logs. +To do this, execute following command:

              +
              kubectl -n scylla-manager logs scylla-manager-controller-0
              +
              +
              +

              The output should be something like:

              +
              {"L":"INFO","T":"2020-09-23T11:25:27.882Z","M":"Scylla Manager Controller started","version":"","build_date":"","commit":"","built_by":"","go_version":"","options":{"Name":"scylla-manager-controller-0","Namespace":"scylla-manager","LogLevel":"debug","ApiAddress":"http://127.0.0.1:5080/api/v1"},"_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
              +{"L":"INFO","T":"2020-09-23T11:25:28.435Z","M":"Registering Components.","_trace_id":"LQEJV3kDR5Gx9M3XQ2YnnQ"}
              +
              +
              +

              To check logs of Scylla Manager itself, use following command:

              +
              kubectl -n scylla-manager logs scylla-manager-scylla-manager-7bd9f968b9-w25jw
              +
              +
              +

              The output should be something like:

              +
              {"L":"INFO","T":"2020-09-23T11:26:53.238Z","M":"Scylla Manager Server","version":"2.1.2-0.20200816.76cc4dcc","pid":1,"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
              +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Using config","config":{"HTTP":"127.0.0.1:5080","HTTPS":"","TLSCertFile":"/var/lib/scylla-manager/scylla_manager.crt","TLSKeyFile":"/var/lib/scylla-manager/scylla_manager.key","TLSCAFile":"","Prometheus":":56090","PrometheusScrapeInterval":5000000000,"debug":"127.0.0.1:56112","Logger":{"Mode":"stderr","Level":"info","Development":false},"Database":{"Hosts":["scylla-manager-cluster-manager-dc-manager-rack-0.scylla-manager.svc"],"SSL":false,"User":"","Password":"","LocalDC":"","Keyspace":"scylla_manager","MigrateDir":"/etc/scylla-manager/cql","MigrateTimeout":30000000000,"MigrateMaxWaitSchemaAgreement":300000000000,"ReplicationFactor":1,"Timeout":600000000,"TokenAware":true},"SSL":{"CertFile":"","Validate":true,"UserCertFile":"","UserKeyFile":""},"Healthcheck":{"Timeout":250000000,"SSLTimeout":750000000},"Backup":{"DiskSpaceFreeMinPercent":10,"AgeMax":43200000000000},"Repair":{"SegmentsPerRepair":1,"ShardParallelMax":0,"ShardFailedSegmentsMax":100,"PollInterval":200000000,"ErrorBackoff":300000000000,"AgeMax":0,"ShardingIgnoreMsbBits":12}},"config_files":["/mnt/etc/scylla-manager/scylla-manager.yaml"],"_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
              +{"L":"INFO","T":"2020-09-23T11:26:54.519Z","M":"Checking database connectivity...","_trace_id":"xQhkJ0OuR8e6iMDEpM62Hg"}
              +
              +
              +

              If there are no errors in the logs, let’s spin a Scylla Cluster.

              +
              +
              +

              Cluster registration

              +

              When the Scylla Manager is fully up and running, lets create a regular instance of Scylla cluster.

              +

              See generic tutorial to spawn your cluster.

              +

              Note: If you already have some Scylla Clusters, after installing Manager they should be +automatically registered in Scylla Manager.

              +

              Once cluster reaches desired node count, cluster status will be updated with ID under which it was registered in Manager.

              +
              kubectl -n scylla describe Cluster
              +
              +[...]
              +Status:
              + Manager Id:  d1d532cd-49f2-4c97-9263-25126532803b
              + Racks:
              +   us-east-1a:
              +     Members:        3
              +     Ready Members:  3
              +     Version:        4.0.0
              +
              +
              +

              You can use this ID to talk to Scylla Manager using sctool CLI installed in Scylla Manager Pod. +You can also use Cluster name in namespace/cluster-name format.

              +
              kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
              +
              +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
              +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
              +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
              +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
              +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
              +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
              +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
              +
              +
              +

              Scylla Manager by default registers recurring healhcheck tasks for Agent and for each of the enabled frontends (CQL, Alternator).

              +

              In this task listing we can see CQL and REST healthchecks.

              +
              +
              +

              Task scheduling

              +

              You can either define tasks prior Cluster creation, or for existing Cluster. +Let’s edit already running cluster definition to add repair and backup task.

              +
              kubectl -n scylla edit Cluster simple-cluster
              +
              +
              +

              Add following task definition to Cluster spec:

              +
                repairs:
              +    - name: "users repair"
              +      keyspace: ["users"]
              +      interval: "1d"
              +  backup:
              +    - name: "weekly backup"
              +      location: ["s3:cluster-backups"]
              +      retention: 3
              +      interval: "7d"
              +    - name: "daily backup"
              +      location: ["s3:cluster-backups"]
              +      retention: 7
              +      interval: "1d"
              +
              +
              +

              For full task definition configuration consult Scylla Cluster CRD.

              +

              Note: Scylla Manager Agent must have access to above bucket prior the update in order to schedule backup task. +Consult Scylla Manager documentation for details on how to set it up.

              +

              Scylla Manager Controller will spot this change and will schedule tasks in Scylla Manager.

              +
              kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task list
              +
              +Cluster: scylla/simple-cluster (d1d532cd-49f2-4c97-9263-25126532803b)
              +╭─────────────────────────────────────────────────────────────┬──────────────────────────────────────┬────────────────────────────────┬────────╮
              +│ Task                                                        │ Arguments                            │ Next run                       │ Status │
              +├─────────────────────────────────────────────────────────────┼──────────────────────────────────────┼────────────────────────────────┼────────┤
              +│ healthcheck/400b2723-eec5-422a-b7f3-236a0e10575b            │                                      │ 23 Sep 20 14:28:42 CEST (+15s) │ DONE   │
              +│ backup/275aae7f-c436-4fc8-bcec-479e65fb8372                 │ -L s3:cluster-backups  --retention 3 │ 23 Sep 20 14:28:58 CEST (+7d)  │ NEW    │
              +│ healthcheck_rest/28169610-a969-4c20-9d11-ab7568b8a1bd       │                                      │ 23 Sep 20 14:29:57 CEST (+1m)  │ NEW    │
              +│ repair/d4946360-c29d-4bb4-8b9d-619ada495c2a                 │                                      │ 23 Sep 20 14:38:42 CEST        │ NEW    │
              +╰─────────────────────────────────────────────────────────────┴──────────────────────────────────────┴────────────────────────────────┴────────╯
              +
              +
              +

              As you can see, we have two new tasks, weekly recurring backup, and one repair which should start shortly.

              +

              To check progress of run you can use following command:

              +
              kubectl -n scylla-manager exec -ti scylla-manager-scylla-manager-7bd9f968b9-w25jw -- sctool task progress --cluster d1d532cd-49f2-4c97-9263-25126532803b repair/d4946360-c29d-4bb4-8b9d-619ada495c2a
              +Status:         RUNNING
              +Start time:     23 Sep 20 14:38:42 UTC
              +Duration:       13s
              +Progress:       2.69%
              +Datacenters:
              +  - us-east-1
              ++--------------------+-------+
              +| system_auth        | 8.06% |
              +| system_distributed | 0.00% |
              +| system_traces      | 0.00% |
              ++--------------------+-------+
              +
              +
              +

              Other tasks can be also tracked using the same command, but using different task ID. +Task IDs are present in Cluster Status as well as in task listing.

              +
              +
              +

              Clean Up

              +

              To clean up all resources associated with Scylla Manager, you can run the commands below.

              +

              NOTE: this will destroy your Scylla Manager database and delete all of its associated data.

              +
              kubectl delete -f examples/common/manager.yaml
              +
              +
              +
              +
              +

              Troubleshooting

              +

              Manager is not running

              +

              If the Scylla Manager does not come up, the first step would be to examine the Manager and Controller logs:

              +
              kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-controller
              +kubectl -n scylla-manager logs -f scylla-manager-controller-0 scylla-manager-scylla-manager-7bd9f968b9-w25jw
              +
              +
              +

              My task wasn’t scheduled

              +

              If your task wasn’t scheduled, Cluster status will be updated with error messages for each failed task. +You can also consult Scylla Manager logs.

              +

              Example:

              +

              Following status describes error when backup task cannot be scheduled, due to lack of access to bucket:

              +
              Status:
              +  Backups:
              +    Error:     create backup target: location is not accessible: 10.100.16.62: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.100.16.62 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.107.193.33: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.107.193.33 and run "scylla-manager-agent check-location -L s3:manager-test --debug"; 10.109.197.60: giving up after 2 attempts: after 15s: timeout - make sure the location is correct and credentials are set, to debug SSH to 10.109.197.60 and run "scylla-manager-agent check-location -L s3:manager-test --debug"
              +    Id:        00000000-0000-0000-0000-000000000000
              +    Interval:  0
              +    Location:
              +      s3:manager-test
              +    Name:         adhoc backup
              +    Num Retries:  3
              +    Retention:    3
              +    Start Date:   now
              +  Manager Id:     2b9dbe8c-9daa-4703-a66d-c29f63a917c8
              +  Racks:
              +    us-east-1a:
              +      Members:        3
              +      Ready Members:  3
              +      Version:        4.0.0
              +
              +
              +

              Because Controller is infinitely retrying to schedule each defined task, once permission issues will be resolved, +task should appear in task listing and Cluster status.

              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/migration.html b/v1.9/migration.html new file mode 100644 index 00000000000..1166044c7b1 --- /dev/null +++ b/v1.9/migration.html @@ -0,0 +1,732 @@ + + + + + + + + + + + + + Version migrations | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Version migrations

              +
              +

              v0.3.0 -> v1.0.0 migration

              +

              v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common kind +which is easier to disambiguate (ScyllaCluster). +This change is backward incompatible, which means manual migration is needed.

              +

              This procedure involves having two CRDs registered at the same time. We will detach Scylla Pods +from Scylla Operator for a short period to ensure that nothing is garbage collected when Scylla Operator is upgraded. +Compared to the upgrade guide where full deletion is requested, this procedure shouldn’t cause downtimes. +Although detaching resources from their controller is considered hacky. This means that you shouldn’t run procedure +out of the box on production. Make sure this procedure works well multiple times on your staging environment first.

              +

              Read the whole procedure and make sure you understand what is going on before executing any of the commands!

              +

              In case of any issues or questions regarding this procedure, you’re welcomed on our Scylla Users Slack +on #kubernetes channel.

              +
              +
              +

              Procedure

              +
                +
              1. Execute this whole procedure for each cluster sequentially. To get a list of existing clusters execute the following

                +
                kubectl -n scylla get cluster.scylla.scylladb.com
                +
                +NAME             AGE
                +simple-cluster   30m
                +
                +
                +

                All below commands will use scylla namespace and simple-cluster as a cluster name.

                +
              2. +
              3. Make sure you’re using v1.0.0 tag:

                +
                git checkout v1.0.0
                +
                +
                +
              4. +
              5. Upgrade your cert-manager to v1.0.0. If you installed it from a static file from this repo, simply execute the following:

                +
                 kubectl apply -f examples/common/cert-manager.yaml
                +
                +
                +

                If your cert-manager was installed in another way, follow official instructions on cert-manager website.

                +
              6. +
              7. examples/common/operator.yaml file contains multiple resources. Extract only CustomResourceDefinition to separate file.

              8. +
              9. Install v1.0.0 CRD definition from file created in the previous step:

                +
                kubectl apply -f examples/common/crd.yaml
                +
                +
                +
              10. +
              11. Save your existing simple-cluster Cluster definition to a file:

                +
                kubectl -n scylla get cluster.scylla.scylladb.com simple-cluster -o yaml > existing-cluster.yaml
                +
                +
                +
              12. +
              13. Migrate Kind and ApiVersion to new values using:

                +
                sed -i 's/scylla.scylladb.com\/v1alpha1/scylla.scylladb.com\/v1/g' existing-cluster.yaml
                +sed -i 's/kind: Cluster/kind: ScyllaCluster/g' existing-cluster.yaml
                +
                +
                +
              14. +
              15. Install migrated CRD instance

                +
                kubectl apply -f existing-cluster.yaml
                +
                +
                +

                At this point, we should have two CRDs describing your Scylla cluster, although the new one is not controlled by the Operator.

                +
              16. +
              17. Get UUID of newly created ScyllaCluster resource:

                +
                kubectl -n scylla get ScyllaCluster simple-cluster --template="{{ .metadata.uid }}"
                +
                +12a3678d-8511-4c9c-8a48-fa78d3992694
                +
                +
                +

                Save output UUID somewhere, it will be referred as <new-cluster-uid> in commands below.

                +

                Depending on your shell, you might get additional ‘%’ sign at the end of UUID, make sure to remove it!

                +
              18. +
              19. Upgrade ClusterRole attached to each of the Scylla nodes to grant them permission to lookup Scylla clusters:

                +
                kubectl patch ClusterRole simple-cluster-member --type "json" -p '[{"op":"add","path":"/rules/-","value":{"apiGroups":["scylla.scylladb.com"],"resources":["scyllaclusters"],"verbs":["get"]}}]'
                +
                +
                +

                Amend role name according to your cluster name, it should look like <scylla-cluster-name>-member.

                +
              20. +
              21. Get a list of all Services associated with your cluster. First get list of all services:

                +
                 kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
                +
                + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
                + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          109m
                + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
                + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   108m
                + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   106m
                +
                +
                +
              22. +
              23. For each service, change its ownerReference to point to new CRD instance:

                +
                 kubectl -n scylla patch svc <cluster-svc-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
                +
                +
                +

                Replace <cluster-svc-name> with Service name, and <new-cluster-uid> with saved UUID from one of the previous steps.

                +
              24. +
              25. Get a list of all Services again to see if none was deleted. Check also “Age” column, it shouldn’t be lower than previous result.

                +
                 kubectl -n scylla get svc -l "scylla/cluster=simple-cluster"
                +
                + NAME                                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                           AGE
                + simple-cluster-client                   ClusterIP   None           <none>        9180/TCP                                                          110m
                + simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.23.96    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   110m
                + simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.66.22    <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   109m
                + simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.246.25   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   107m
                +
                +
                +
              26. +
              27. Get a list of StatefulSets associated with your cluster:

                +
                kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
                +
                +NAME                                  READY   AGE
                +simple-cluster-us-east-1-us-east-1a   3/3     104m
                +
                +
                +
              28. +
              29. For each StatefulSet from previous step, change its ownerReference to point to new CRD instance.

                +
                 kubectl -n scylla patch sts <cluster-sts-name> --type='json' -p='[{"op": "replace", "path": "/metadata/ownerReferences/0/apiVersion", "value":"scylla.scylladb.com/v1"}, {"op": "replace", "path": "/metadata/ownerReferences/0/kind", "value":"ScyllaCluster"}, {"op": "replace", "path": "/metadata/ownerReferences/0/uid", "value":"<new-cluster-uid>"}]'
                +
                +
                +

                Replace <cluster-sts-name> with StatefulSet name, and <new-cluster-uid> with saved UUID from one of the previous steps.

                +
              30. +
              31. Now when all k8s resources bound to Scylla are attached to new CRD, we can remove 0.3.0 Operator and old CRD definition. +Checkout v0.3.0 version, and remove Scylla Operator, and old CRD:

                +
                 git checkout v0.3.0
                + kubectl delete -f examples/generic/operator.yaml
                +
                +
                +
              32. +
              33. Checkout v1.0.0, and install upgraded Scylla Operator:

                +
                 git checkout v1.0.0
                + kubectl apply -f examples/common/operator.yaml
                +
                +
                +
              34. +
              35. Wait until Scylla Operator boots up:

                +
                 kubectl -n scylla-operator-system wait --for=condition=ready pod --all --timeout=600s
                +
                +
                +
              36. +
              37. Get a list of StatefulSets associated with your cluster:

                +
                kubectl -n scylla get sts -l "scylla/cluster=simple-cluster"
                +
                +NAME                                  READY   AGE
                +simple-cluster-us-east-1-us-east-1a   3/3     104m
                +
                +
                +
              38. +
              39. For each StatefulSet from previous step, change its sidecar container image to v1.0.0, and wait until change will be propagated. This step will initiate a rolling restart of pods one by one.

                +
                kubectl -n scylla patch sts <cluster-sts> --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/initContainers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
                +kubectl -n scylla rollout status sts <cluster-sts>
                +
                +
                +

                Replace <cluster-sts-name> with StatefulSet name.

                +
              40. +
              41. If you’re using Scylla Manager, bump Scylla Manager Controller image to v1.0.0

                +
                 kubectl -n scylla-manager-system patch sts scylla-manager-controller --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"scylladb/scylla-operator:v1.0.0"}]'
                +
                +
                +
              42. +
              43. Your Scylla cluster is now migrated to v1.0.0.

              44. +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/monitoring.html b/v1.9/monitoring.html new file mode 100644 index 00000000000..8a9ed222246 --- /dev/null +++ b/v1.9/monitoring.html @@ -0,0 +1,779 @@ + + + + + + + + + + + + + Monitoring | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Monitoring

              +

              Scylla Operator 1.8 introduced a new API resource ScyllaDBMonitoring, allowing users to deploy a managed monitoring +setup for their Scylla Clusters.

              +
              apiVersion: scylla.scylladb.com/v1alpha1
              +kind: ScyllaDBMonitoring
              +metadata:
              +  name: example
              +spec:
              +  type: Platform
              +  endpointsSelector:
              +    matchLabels:
              +      app.kubernetes.io/name: scylla
              +      scylla-operator.scylladb.com/scylla-service-type: identity
              +      scylla/cluster: replace-with-your-scyllacluster-name
              +  components:
              +    prometheus:
              +      storage:
              +        volumeClaimTemplate:
              +          spec:
              +            resources:
              +              requests:
              +                storage: 1Gi
              +    grafana:
              +      exposeOptions:
              +        webInterface:
              +          ingress:
              +            ingressClassName: haproxy
              +            dnsDomains:
              +            - test-grafana.test.svc.cluster.local
              +            annotations:
              +              haproxy-ingress.github.io/ssl-passthrough: "true"
              +
              +
              +

              For details, refer to the below command:

              +
              $ kubectl explain scylladbmonitorings.scylla.scylladb.com/v1alpha1
              +
              +
              +
              +

              Deploy managed monitoring

              +

              Note: as of v1.8, ScyllaDBMonitoring is experimental. The API is currently in version v1alpha1 and may change in future versions.

              +
              +

              Requirements

              +

              Before you can set up your ScyllaDB monitoring, you need Scylla Operator already installed in your Kubernetes cluster. +For more information on how to deploy Scylla Operator, see:

              + +

              The above example of the monitoring setup also makes use of HAProxy Ingress and Prometheus Operator. +You can deploy them in your Kubernetes cluster using the provided third party examples. If you already have them deployed +in your cluster, you can skip the below steps.

              +
              +

              Deploy Prometheus Operator

              +

              Deploy Prometheus Operator using kubectl:

              +
              $ kubectl -n prometheus-operator apply --server-side -f ./examples/third-party/prometheus-operator
              +
              +
              +
              +
              Wait for Prometheus Operator to roll out
              +
              $ kubectl -n prometheus-operator rollout status --timeout=5m deployments.apps/prometheus-operator
              +deployment "prometheus-operator" successfully rolled out
              +
              +
              +
              +
              +
              +

              Deploy HAProxy Ingress

              +

              Deploy HAProxy Ingress using kubectl:

              +
              $ kubectl -n haproxy-ingress apply --server-side -f ./examples/third-party/haproxy-ingress
              +
              +
              +
              +
              Wait for HAProxy Ingress to roll out
              +
              $ kubectl -n haproxy-ingress rollout status --timeout=5m deployments.apps/haproxy-ingress
              +deployment "haproxy-ingress" successfully rolled out
              +
              +
              +
              +
              +
              +
              +

              Deploy ScyllaDBMonitoring

              +

              First, update the endpointsSelector in examples/monitoring/v1alpha1/scylladbmonitoring.yaml with a label +matching your ScyllaCluster instance name.

              +

              Deploy the monitoring setup using kubectl:

              +
              $ kubectl -n scylla apply --server-side -f ./examples/monitoring/v1alpha1/scylladbmonitoring.yaml
              +
              +
              +

              Scylla Operator will notice the new ScyllaDBMonitoring object, and it will reconcile all necessary resources.

              +
              +

              Wait for ScyllaDBMonitoring to roll out

              +
              $ kubectl wait --for='condition=Progressing=False' scylladbmonitorings.scylla.scylladb.com/example
              +scylladbmonitoring.scylla.scylladb.com/example condition met
              +
              +$ kubectl wait --for='condition=Degraded=False' scylladbmonitorings.scylla.scylladb.com/example
              +scylladbmonitoring.scylla.scylladb.com/example condition met
              +
              +$ kubectl wait --for='condition=Available=True' scylladbmonitorings.scylla.scylladb.com/example
              +scylladbmonitoring.scylla.scylladb.com/example condition met
              +
              +
              +
              +
              +

              Wait for Prometheus to roll out

              +
              $ kubectl rollout status --timeout=5m statefulset.apps/prometheus-example
              +statefulset rolling update complete 1 pods at revision prometheus-example-65b89d55bb...
              +
              +
              +
              +
              +

              Wait for Grafana to roll out

              +
              $ kubectl rollout status --timeout=5m deployments.apps/example-grafana
              +deployment "example-grafana" successfully rolled out
              +
              +
              +
              +
              +
              +

              Accessing Grafana

              +

              For accessing Grafana service from outside the Kubernetes cluster we recommend using an Ingress, although there are many other ways to do so. +When using Ingress, what matters is to direct your packets to the ingress controller Service/Pods and have the correct TLS SNI field set by the caller when reaching out to the service, so it is routed properly, and your client can successfully validate the grafana serving certificate. +This is easier when you are using a real DNS domain that resolves to your Ingress controller’s IP address but most clients and tools allow setting the SNI field manually.

              +
              +
              +

              Prerequisites

              +

              To access Grafana, you first need to collect the serving CA and the credentials.

              +
              $ GRAFANA_SERVING_CERT="$( kubectl -n scylla get secret/example-grafana-serving-ca --template '{{ index .data "tls.crt" }}' | base64 -d )"
              +$ GRAFANA_USER="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "username" }}' | base64 -d )"
              +$ GRAFANA_PASSWORD="$( kubectl -n scylla get secret/example-grafana-admin-credentials --template '{{ index .data "password" }}' | base64 -d )"
              +
              +
              +
              +
              +

              Connecting through Ingress using a resolvable domain

              +

              In production clusters, the Ingress controller and appropriate DNS records should be set up already. Often there is already a generic wildcard record like *.app.mydomain pointing to the Ingress controller’s external IP. For custom service domains, it is usually a CNAME pointing to the Ingress controller’s A record.

              +

              Note: The ScyllaDBMonitoring example creates an Ingress object with test-grafana.test.svc.cluster.local DNS domain that you should adjust to your domain. Below examples use example-grafana.apps.mydomain.

              +

              Note: To test a resolvable domain from your machine without creating DNS records, you can adjust /etc/hosts or similar.

              +
              $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://example-grafana.apps.mydomain" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
              +200
              +
              +
              +
              +
              +

              Connecting through Ingress using an unresolvable domain

              +

              To connect to an Ingress without a resolvable domain you first need to find out your Ingress controller’s IP that can be resolved externally. Again, there are many ways to do so beyond the below examples.

              +

              Unless stated otherwise, we assume your Ingress is running on port 443.

              +
              $ INGRESS_PORT=443
              +
              +
              +
              +

              Variants

              +
              +
              Ingress ExternalIP
              +

              When you are running in a real cluster there is usually a cloud LoadBalancer or a bare metal alternative providing you with an externally reachable IP address.

              +
              $ INGRESS_IP="$( kubectl -n=haproxy-ingress get service/haproxy-ingress --template='{{ ( index .status.loadBalancer.ingress 0 ).ip }}' )"
              +
              +
              +
              +
              +
              Ingress NodePort
              +

              NodePort is slightly less convenient, but it’s available in development clusters as well.

              +
              $ INGRESS_IP="$( kubectl get nodes --template='{{ $internal_ip := "" }}{{ $external_ip := "" }}{{ range ( index .items 0 ).status.addresses }}{{ if eq .type "InternalIP" }}{{ $internal_ip = .address }}{{ else if eq .type "ExternalIP" }}{{ $external_ip = .address }}{{ end }}{{ end }}{{ if $external_ip }}{{ $external_ip }}{{ else }}{{ $internal_ip }}{{ end }}' )"
              +$ INGRESS_PORT="$( kubectl -n=haproxy-ingress get services/haproxy-ingress --template='{{ range .spec.ports }}{{ if eq .port 443 }}{{ .nodePort }}{{ end }}{{ end }}' )"
              +
              +
              +
              +
              +
              Connection
              +
              $ curl --fail -s -o /dev/null -w '%{http_code}' -L --cacert <( echo "${GRAFANA_SERVING_CERT}" ) "https://test-grafana.test.svc.cluster.local:${INGRESS_PORT}" --resolve "test-grafana.test.svc.cluster.local:${INGRESS_PORT}:${INGRESS_IP}" --user "${GRAFANA_USER}:${GRAFANA_PASSWORD}"
              +200
              +
              +
              +
              +
              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/nodeoperations/automatic_cleanup.html b/v1.9/nodeoperations/automatic_cleanup.html new file mode 100644 index 00000000000..0c13ff0336f --- /dev/null +++ b/v1.9/nodeoperations/automatic_cleanup.html @@ -0,0 +1,571 @@ + + + + + + + + + + + + + Automatic cleanup and replacement in case when k8s node is lost | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Automatic cleanup and replacement in case when k8s node is lost

              +

              In case when your k8s cluster loses one of the nodes due to incident or explicit removal, Scylla Pods may become unschedulable due to PVC node affinity.

              +

              When automaticOrphanedNodeCleanup flag is enabled in your ScyllaCluster, Scylla Operator will perform automatic +node replacement of a Pod which lost his bound resources.

              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/nodeoperations/index.html b/v1.9/nodeoperations/index.html new file mode 100644 index 00000000000..12493c410e8 --- /dev/null +++ b/v1.9/nodeoperations/index.html @@ -0,0 +1,571 @@ + + + + + + + + + + + + + Node operations using Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Node operations using Scylla Operator

              +
              +
              +

              Choose a topic:

              + +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/nodeoperations/maintenance_mode.html b/v1.9/nodeoperations/maintenance_mode.html new file mode 100644 index 00000000000..28d40decace --- /dev/null +++ b/v1.9/nodeoperations/maintenance_mode.html @@ -0,0 +1,580 @@ + + + + + + + + + + + + + Maintenance mode | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + + + +
              +

              Maintenance mode

              +

              When maintenance mode is enabled, readiness probe of Scylla Pod will always return failure and liveness probe will always succeed. This causes that Pod under maintenance +is being removed from K8s Load Balancer and DNS registry but Pod itself stays alive.

              +

              This allows the Scylla Operator to interact with Scylla and Scylla dependencies inside the Pod. +For example user may turn off Scylla process, do something with the filesystem and bring the process back again.

              +

              To enable maintenance mode add scylla/node-maintenance label to service in front of Scylla Pod.

              +
              kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance=""
              +
              +
              +

              To disable, simply remove this label from service.

              +
              kubectl -n scylla label svc simple-cluster-us-east1-b-us-east1-2 scylla/node-maintenance-
              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/nodeoperations/replace_node.html b/v1.9/nodeoperations/replace_node.html new file mode 100644 index 00000000000..e355e18a316 --- /dev/null +++ b/v1.9/nodeoperations/replace_node.html @@ -0,0 +1,654 @@ + + + + + + + + + + + + + Replacing a Scylla node | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + + + +
              +

              Replacing a Scylla node

              +
              +

              Replacing a dead node

              +

              In the case of a host failure, it may not be possible to bring back the node to life.

              +

              Replace dead node operation will cause the other nodes in the cluster to stream data to the node that was replaced. +This operation can take some time (depending on the data size and network bandwidth).

              +

              This procedure is for replacing one dead node. To replace more than one dead node, run the full procedure to completion one node at a time

              +

              Procedure

              +
                +
              1. Verify the status of the node using nodetool status command, the node with status DN is down and need to be replaced

                +
                kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
                +Datacenter: us-east-1
                +=====================
                +Status=Up/Down
                +|/ State=Normal/Leaving/Joining/Moving
                +--  Address        Load       Tokens       Owns    Host ID                               Rack
                +UN  10.43.125.110  74.63 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
                +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
                +DN  10.43.43.51    74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
                +
                +
                +
              2. +
              3. Identify service which is bound to down node by checking IP address

                +
                kubectl -n scylla get svc
                +NAME                                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                           AGE
                +simple-cluster-client                   ClusterIP   None            <none>        9180/TCP                                                          3h12m
                +simple-cluster-us-east-1-us-east-1a-0   ClusterIP   10.43.231.189   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h12m
                +simple-cluster-us-east-1-us-east-1a-1   ClusterIP   10.43.125.110   <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h11m
                +simple-cluster-us-east-1-us-east-1a-2   ClusterIP   10.43.43.51     <none>        7000/TCP,7001/TCP,7199/TCP,10001/TCP,9042/TCP,9142/TCP,9160/TCP   3h5m
                +
                +
                +
              4. +
              5. Drain node which we would like to replace using. This command may delete your data from local disks attached to given node!

                +
                kubectl drain gke-scylla-demo-default-pool-b4b390a1-6j12 --ignore-daemonsets --delete-local-data
                +
                +
                +

                Pod which will be replaced should enter the Pending state

                +
                kubectl -n scylla get pods
                +NAME                                    READY   STATUS    RESTARTS   AGE
                +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h21m
                +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h19m
                +simple-cluster-us-east-1-us-east-1a-2   0/2     Pending   0          8m14s
                +
                +
                +
              6. +
              7. To being node replacing, add scylla/replace="" label to service bound to pod we are replacing.

                +
                kubectl -n scylla label svc simple-cluster-us-east-1-us-east-1a-2 scylla/replace=""
                +
                +
                +

                Your failed Pod should be recreated on available k8s node

                +
                kubectl -n scylla get pods
                +NAME                                    READY   STATUS    RESTARTS   AGE
                +simple-cluster-us-east-1-us-east-1a-0   2/2     Running   0          3h27m
                +simple-cluster-us-east-1-us-east-1a-1   2/2     Running   0          3h25m
                +simple-cluster-us-east-1-us-east-1a-2   1/2     Running   0          9s
                +
                +
                +

                Because other nodes in cluster must stream data to new node this operation might take some time depending on how much data your cluster stores. +After bootstraping is over, your new Pod should be ready to go. +Old one shouldn’t be no longer visible in nodetool status

                +
                kubectl -n scylla exec -ti simple-cluster-us-east-1-us-east-1a-0 -c scylla -- nodetool status
                +Datacenter: us-east-1
                +=====================
                +Status=Up/Down
                +|/ State=Normal/Leaving/Joining/Moving
                +--  Address        Load       Tokens       Owns    Host ID                               Rack
                +UN  10.43.125.110  74.62 KB   256          ?       8ebd6114-969c-44af-a978-87a4a6c65c3e  us-east-1a
                +UN  10.43.231.189  91.03 KB   256          ?       35d0cb19-35ef-482b-92a4-b63eee4527e5  us-east-1a
                +UN  10.43.191.172  74.77 KB   256          ?       1ffa7a82-c41c-4706-8f5f-4d45a39c7003  us-east-1a
                +
                +
                +
              8. +
              9. Run the repair on the cluster to make sure that the data is synced with the other nodes in the cluster. +You can use Scylla Manager to run the repair.

              10. +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/nodeoperations/restore.html b/v1.9/nodeoperations/restore.html new file mode 100644 index 00000000000..684621841c9 --- /dev/null +++ b/v1.9/nodeoperations/restore.html @@ -0,0 +1,642 @@ + + + + + + + + + + + + + Restore from backup | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + + + +
              +

              Restore from backup

              +

              This procedure will describe how to restore from backup taken using Scylla Manager to a fresh empty cluster of any size.

              +

              First identify to which snapshot you want to restore. To get list of available snapshot execute following command on Scylla Manager Pod.

              +
              sctool backup list -c <CLUSTER_ID> --all-clusters -L <BACKUP_LOCATION>
              +
              +
              +

              Where:

              +
                +
              • CLUSTER_ID - is a name of a cluster or ID under which ScyllaCluster was registered. You can find it in ScyllaCluster Status.

              • +
              • BACKUP_LOCATION - is a location where backup is stored. For example, for bucket called backups stored in AWS S3, location is s3:backups.

              • +
              +
              sctool backup list -c simple-cluster --all-clusters -L s3:backups
              +Snapshots:
              +  - sm_20201227144037UTC (409MiB)
              +  - sm_20201228145917UTC (434MiB)
              +Keyspaces:
              +  - users (9 tables)
              +  - system_auth (2 tables)
              +  - system_distributed (3 tables)
              +  - system_schema (13 tables)
              +  - system_traces (5 tables)
              +
              +
              +

              To get the list of files use:

              +
              sctool backup files -c <CLUSTER_ID> -L <BACKUP_LOCATION> -T <SNAPSHOT_TAG>
              +
              +
              +

              Where:

              +
                +
              • SNAPSHOT_TAG - name of snapshot you want to restore.

              • +
              +

              Before we start restoring the data, we have to restore the schema. +The first output line is a path to schemas archive, for example:

              +
              s3://backups/backup/schema/cluster/ed63b474-2c05-4f4f-b084-94541dd86e7a/task_287791d9-c257-4850-aef5-7537d6e69d90_tag_sm_20201228145917UTC_schema.tar.gz      ./
              +
              +
              +

              To download this archive you can use AWS CLI tool aws s3 cp.

              +

              This archive contains a single CQL file for each keyspace in the backup.

              +
              tar -ztvf task_287791d9-c257-4850-aef5-7537d6e69d90_tag_sm_20201228145917UTC_schema.tar.gz
              +-rw------- 0/0           12671 2020-12-28 13:17 users.cql
              +-rw------- 0/0            2216 2020-12-28 13:17 system_auth.cql
              +-rw------- 0/0             921 2020-12-28 13:17 system_distributed.cql
              +-rw------- 0/0           12567 2020-12-28 13:17 system_schema.cql
              +-rw------- 0/0            4113 2020-12-28 13:17 system_traces.cql
              +
              +
              +

              Extract this archive and copy each schema file to one of the cluster Pods by:

              +
              kubectl -n scylla cp users.cql simple-cluster-us-east-1-us-east-1a-0:/tmp/users.cql -c scylla
              +
              +
              +

              To import schema simply execute:

              +
              kubectl -n scylla exec simple-cluster-us-east-1-us-east-1a-0 -c scylla -- cqlsh -f /tmp/users.cql
              +
              +
              +

              Once the schema is recreated we can proceed to downloading data files.

              +

              First let’s save a list of snapshot files to file called backup_files.out:

              +
              kubectl -n scylla-manager exec deployment.apps/scylla-manager-controller -- sctool backup files -c simple-cluster -L s3:backups -T sm_20201228145917UTC > backup_files.out
              +
              +
              +

              We will be using sstableloader to restore data. sstableloader needs a specific directory structure to work namely: <keyspace>/<table>/<contents> +To create this directory structure and download all the files execute these commands:

              +
              mkdir snapshot
              +cd snapshot
              +# Create temporary directory structure.
              +cat ../backup_files.out | awk '{print $2}' | xargs mkdir -p
              +# Download snapshot files.
              +cat ../backup_files.out | xargs -n2 aws s3 cp
              +
              +
              +

              To load data into cluster pass cluster address to sstableloader together with path to data files and credentials:

              +
              sstableloader -d 'simple-cluster-us-east-1-us-east-1a-0.scylla.svc,simple-cluster-us-east-1-us-east-1a-1.scylla.svc,simple-cluster-us-east-1-us-east-1a-2.scylla.svc' ./users/data_0 --username scylla --password <password>
              +
              +
              +

              Depending on how big is your data set, this operation may take some time. +Once it finishes, data from the snapshot is restored and you may clean up the host.

              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/nodeoperations/scylla_upgrade.html b/v1.9/nodeoperations/scylla_upgrade.html new file mode 100644 index 00000000000..dc774828c73 --- /dev/null +++ b/v1.9/nodeoperations/scylla_upgrade.html @@ -0,0 +1,653 @@ + + + + + + + + + + + + + Upgrading version of Scylla | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Upgrading version of Scylla

              +

              To upgrade Scylla version using Operator user have to modify existing ScyllaCluster definition.

              +

              In this example cluster will be upgraded to version 4.4.5.

              +
              kubectl -n scylla patch ScyllaCluster simple-cluster  -p '{"spec":{"version": "4.4.5"}}' --type=merge
              +
              +
              +

              Operator supports two types of version upgrades:

              +
                +
              1. Patch upgrade

              2. +
              3. Generic upgrade

              4. +
              +

              Patch upgrade

              +

              Patch upgrade is executed when only patch version change is detected according to semantic versioning format. +Procedure simply rolls out a restart of whole cluster and upgrades Scylla container image for each node one by one.

              +

              Example: 4.0.0 -> 4.0.1

              +

              Generic upgrade

              +

              Generic upgrades are executed for the non patch version changes.

              +

              Example: 4.0.0 -> 2020.1.0 or 4.0.0 -> 4.1.0 or even 4.0.0 -> nightly

              +

              User can observe current state of upgrade in ScyllaCluster status.

              +
              kubectl -n scylla describe ScyllaCluster simple-cluster
              +[...]
              +Status:
              +  Racks:
              +    us-east-1a:
              +      Members:        3
              +      Ready Members:  3
              +      Version:        4.1.9
              +  Upgrade:
              +    Current Node:         simple-cluster-us-east-1-us-east-1a-2
              +    Current Rack:         us-east-1a
              +    Data Snapshot Tag:    so_data_20201228135002UTC
              +    From Version:         4.1.9
              +    State:                validate_upgrade
              +    System Snapshot Tag:  so_system_20201228135002UTC
              +    To Version:           4.2.2
              +
              +
              +

              Each upgrade begins with taking a snapshot of system and system_schema keyspaces on all nodes in parallel. +Name of this snapshot tag is saved in upgrade status under System Snapshot Tag.

              +

              Before nodes in rack are upgraded, underlying StatefulSet is changed to use OnDelete UpgradeStrategy. +This allows Operator have a full control over when Pod image is changed.

              +

              When a node is being upgraded, maintenance mode is enabled, then the node is drained and snapshot of all data keyspaces is taken. +Snapshot tag is saved under Data Snapshot Tag and is the same for all nodes during the procedure. +Once everything is set up, maintenance mode is disabled and Scylla Pod is deleted. Underlying StatefulSet will bring up a new +Pod with upgraded version. +Once Pod will become ready, data snapshot from this particular node is removed, and Operator moves to next node.

              +

              Once every rack is upgraded, system snapshot is removed from all nodes in parallel and previous StatefulSet UpgradeStrategy is restored. +At this point, all your nodes should be already in desired version.

              +

              Current state of upgrade can be traced using Current Node, Current Rack and State status fields.

              +
                +
              • Current Node shows which node is being upgraded.

              • +
              • Current Rack displays which rack is being upgraded.

              • +
              • State contain information at which stage upgrade is.

              • +
              +

              State can have following values:

              +
                +
              • begin_upgrade - upgrade is starting

              • +
              • check_schema_agreement - Operator waits until all nodes reach schema agreement. It waits for it for 1 minute, prints an error log message and check is retried.

              • +
              • create_system_backup - system keyspaces snapshot is being taken

              • +
              • find_next_rack - Operator finds out which rack must be upgraded next, decision is saved in Current Rack

              • +
              • upgrade_image_in_pod_spec - Image and UpgradeStrategy is upgraded in underlying StatefulSet

              • +
              • find_next_node - Operator finds out which node must be upgraded next, decision is saved in Current Node

              • +
              • enable_maintenance_mode - maintenance mode is being enabled

              • +
              • drain_node - node is being drained

              • +
              • backup_data - snapshot of data keyspaces is being taken

              • +
              • disable_maintenance_mode - maintenance mode is being disabled

              • +
              • delete_pod - Scylla Pod is being deleted

              • +
              • validate_upgrade - Operator validates if new pod enters Ready state and if Scylla version is upgraded

              • +
              • clear_data_backup - snapshot of data keyspaces is being removed

              • +
              • clear_system_backup - snapshot of system keyspaces is being removed

              • +
              • restore_upgrade_strategy - restore UpgradeStrategy in underlying StatefulSet

              • +
              • finish_upgrade - upgrade cleanup

              • +
              +

              Recovering from upgrade failure

              +

              Upgrade may get stuck on validate_upgrade stage. This happens when Scylla Pod refuses to properly boot up.

              +

              To continue with upgrade, first turn off operator by scaling Operator replicas to zero:

              +
              kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=0
              +
              +
              +

              Then user have to manually resolve issue with Scylla by checking what is the root cause of a failure in Scylla container logs. +If needed data and system keyspaces SSTable snapshots are available on the node. You can check ScyllaCluster status for their names.

              +

              Once issue is resolved and Scylla Pod is up and running (Pod is in Ready state), scale Operator back to two replicas:

              +
              kubectl -n scylla-operator scale deployment.apps/scylla-operator --replicas=2
              +
              +
              +

              Operator should continue upgrade process from where it left off.

              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/objects.inv b/v1.9/objects.inv new file mode 100644 index 00000000000..be70941f91c --- /dev/null +++ b/v1.9/objects.inv @@ -0,0 +1,5 @@ +# Sphinx inventory version 2 +# Project: Scylla Operator +# Version: +# The remainder of this file is compressed using zlib. +xڅTˎ ((hfDMFJ{lX<,c={).uԀuZ x?NI8NËI׀;m; -2C<^X%'C<'ACAzDj7*I~AF4KH~oG֢T%!wqуig\Y(Z9G-BruXOZ cK<" aoД T {1cE L1]oa \ No newline at end of file diff --git a/v1.9/performance.html b/v1.9/performance.html new file mode 100644 index 00000000000..4b0e178d932 --- /dev/null +++ b/v1.9/performance.html @@ -0,0 +1,655 @@ + + + + + + + + + + + + + Performance tuning | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Performance tuning

              +

              Scylla Operator 1.6 introduces a new experimental feature allowing users to optimize Kubernetes nodes.

              +
              +

              Node tuning

              +

              Starting from Operator 1.6, a new CRD called NodeConfig is available, allowing users to target Nodes which should be tuned. +When a Node is supposed to be optimized, the Scylla Operator creates a DaemonSet covering these Nodes. +Nodes matching the provided placement conditions will be subject to tuning.

              +

              Below example NodeConfig tunes nodes having scylla.scylladb.com/node-type=scylla label:

              +
              apiVersion: scylla.scylladb.com/v1alpha1
              +kind: NodeConfig
              +metadata:
              + name: cluster
              +spec:
              + placement:
              +   nodeSelector:
              +     scylla.scylladb.com/node-type: scylla
              +
              +
              +

              For more details about new CRD use:

              +
              kubectl explain nodeconfigs.scylla.scylladb.com/v1alpha1
              +
              +
              +

              For all optimizations we use a Python script available in the Scylla image called perftune. +Perftune executes the performance optmizations like tuning the kernel, network, disk devices, spreading IRQs across CPUs and more.

              +

              Tuning consists of two separate optimizations: common node tuning, and tuning based on Scylla Pods and their resource assignment. +Node tuning is executed immediately. Pod tuning is executed when Scylla Pod lands on the same Node.

              +

              Scylla works most efficently when it’s pinned to CPU and not interrupted. +One of the most common causes of context-switching are network interrupts. Packets coming to a node need to be processed, +and this requires CPU shares.

              +

              On K8s we always have at least a couple of processes running on the node: kubelet, kubernetes provider applications, daemons etc. +These processes require CPU shares, so we cannot dedicate entire node processing power to Scylla, we need to leave space for others.
              We take advantage of it, and we pin IRQs to CPUs not used by any Scylla Pods exclusively.

              +

              Tuning resources are created in a special namespace called scylla-operator-node-tuning.

              +

              The tuning is applied only to pods with Guaranteed QoS class. Please double check your ScyllaCluster resource specification +to see if it meets all conditions.

              +
              +
              +

              Kubernetes tuning

              +

              By default, the kubelet uses the CFS quota to enforce pod CPU limits.
              When the node runs many CPU-bound pods, the workload can move around different CPU cores depending on whether the pod +is throttled and which CPU cores are available. +However, kubelet may be configured to assign CPUs exclusively, by setting the CPU manager policy to static.

              +

              Setting up kubelet configuration is provider specific. Please check the docs for your distribution or talk to your +provider.

              +

              Only pods within the Guaranteed QoS class) can take advantage of this option. +When such pod lands on a Node, kubelet will pin them to specific CPUs, and those won’t be part of the shared pool.

              +

              In our case there are two requirements each ScyllaCluster must fulfill to receive a Guaranteed QoS class:

              +
                +
              • resource request and limits must be equal or only limits have to be provided

              • +
              • agentResources must be provided and their requests and limits must be equal, or only limits have to be provided

              • +
              +

              An example of such a ScyllaCluster that receives a Guaranteed QoS class is below:

              +
              apiVersion: scylla.scylladb.com/v1
              +kind: ScyllaCluster
              +metadata:
              +  name: guaranteed-cluster
              +  namespace: scylla
              +spec:
              +  version: 4.5.1
              +  agentVersion: 2.5.2
              +  datacenter:
              +    name: us-east-1
              +    racks:
              +    - name: us-east-1a
              +      members: 3
              +      storage:
              +        capacity: 500Gi
              +      agentResources:
              +        requests:
              +          cpu: 1
              +          memory: 1G
              +        limits:
              +          cpu: 1
              +          memory: 1G
              +      resources:
              +        requests:
              +          cpu: 4
              +          memory: 16G
              +        limits:
              +          cpu: 4
              +          memory: 16G
              +
              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/releases.html b/v1.9/releases.html new file mode 100644 index 00000000000..af760f74e58 --- /dev/null +++ b/v1.9/releases.html @@ -0,0 +1,817 @@ + + + + + + + + + + + + + Releases | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Releases

              +
              +

              Schedule

              +

              We are aiming to ship a new release approximately every 6 weeks. The following release schedule is only advisory, there are no commitments made to hitting these dates.

              + + + + + + + + + + + + + + + +
              ReleaseCode freezeGeneral availability
              1.92022-03-012021-03-08
              +
              +

              Supported releases

              +

              We support the latest 2 releases of the operator to give everyone time to upgrade.

              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              ReleaseGeneral availabilitySupport ends
              1.82023-01-25Release of 1.10
              1.72022-01-27Release of 1.9
              1.62021-12-032023-01-25
              1.52021-09-162022-01-27
              1.42021-08-102021-12-03
              1.32021-06-172021-09-16
              1.22021-05-062021-08-10
              1.12021-03-222021-06-17
              1.02021-01-212021-05-06
              +

              Backport policy

              +

              Usually, only important bug fixes are eligible for being backported. +This may depend on the situation and assessment of the maintainers.

              +
              +
              +
              +

              CI/CD

              +

              We use GitHub actions for our CI/CD. Every merge to a supported branch, or a creation of a tag will automatically trigger a job to build, test and publish the container image and other artifacts like helm charts. Before we publish any image, it must pass the e2e suite.

              +
              +

              Automated promotions

              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              Git referenceTypeContainer image
              masterbranchdocker.io/scylladb/scylla-operator:latest
              vX.Ybranchdocker.io/scylladb/scylla-operator:X.Y
              vX.Y.Ztagdocker.io/scylladb/scylla-operator:X.Y.Z
              vX.Y.Z-alpha.Ntagdocker.io/scylladb/scylla-operator:X.Y.Z-alpha.N
              vX.Y.Z-beta.Ntagdocker.io/scylladb/scylla-operator:X.Y.Z-beta.N
              vX.Y.Z-rc.Ntagdocker.io/scylladb/scylla-operator:X.Y.Z-rc.N
              +
              +

              Generally available

              +

              GA images aren’t build from scratch but rather promoted from an existing release candidates. When we decide a release candidate has the acceptable quality and QA sings it off, the release candidate is promoted to become the GA release. This makes sure the image has exactly the same content and SHA as the tested release candidate.

              +
              +
              +
              +

              Support matrix

              +

              Support matrix table shows the version requirements for a particular scylla-operator version. Be sure to match these requirements, otherwise some functionality will not work.

              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              v1.9v1.8v1.7v1.6v1.5v1.4v1.3v1.2v1.1v1.0
              Kubernetes>=1.21>=1.21>=1.20 && <1.25>=1.19.10 && <1.25>=1.19.10>=1.19.10>=1.19>=1.19>=1.11>=1.11
              CRI APIv1v1alpha2v1alpha2v1alpha2
              Scylla OS>=5.0>=5.0>=4.3>=4.3>=4.3>=4.3>=4.2>=4.2>=4.0>=4.0
              Scylla Enterprise>=2021.1>=2021.1>=2021.1>=2021.1>=2021.1>=2021.1>=2020.1>=2020.1>=2020.1>=2020.1
              Scylla Manager>=2.6>=2.6>=2.2>=2.2>=2.2>=2.2>=2.2>=2.2>=2.2>=2.2
              Scylla Monitoring>=4.0>=4.0>=3.0>=3.0>=1.0>=1.0>=1.0>=1.0>=1.0>=1.0
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/scylla_cluster_crd.html b/v1.9/scylla_cluster_crd.html new file mode 100644 index 00000000000..1931e518a70 --- /dev/null +++ b/v1.9/scylla_cluster_crd.html @@ -0,0 +1,794 @@ + + + + + + + + + + + + + Scylla Cluster CRD | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Scylla Cluster CRD

              +

              Scylla database clusters can be created and configured using the clusters.scylla.scylladb.com custom resource definition (CRD).

              +

              Please refer to the the user guide walk-through for deployment instructions. +This page will explain all the available configuration options on the Scylla CRD.

              +
              +

              Sample

              +
              apiVersion: scylla.scylladb.com/v1
              +kind: ScyllaCluster
              +metadata:
              +  name: simple-cluster
              +  namespace: scylla
              +spec:
              +  version: 2.3.1
              +  repository: scylladb/scylla
              +  developerMode: true
              +  cpuset: false
              +  automaticOrphanedNodeCleanup: true
              +  repairs:
              +  - name: "weekly us-east-1 repair"
              +    intensity: "2"
              +    interval: "7d"
              +    dc: ["us-east-1"]
              +  backups:
              +  - name: "daily users backup"
              +    rateLimit: ["50"]
              +    location: ["s3:cluster-backups"]
              +    interval: "1d"
              +    keyspace: ["users"]
              +  - name: "weekly full cluster backup"
              +    rateLimit: ["50"]
              +    location: ["s3:cluster-backups"]
              +    interval: "7d"
              +  datacenter:
              +    name: us-east-1
              +    racks:
              +      - name: us-east-1a
              +        members: 3
              +        storage:
              +          capacity: 500G
              +          storageClassName: local-raid-disks
              +        resources:
              +          requests:
              +            cpu: 8
              +            memory: 32Gi
              +          limits:
              +            cpu: 8
              +            memory: 32Gi
              +        placement:
              +          nodeAffinity:
              +            requiredDuringSchedulingIgnoredDuringExecution:
              +              nodeSelectorTerms:
              +                - matchExpressions:
              +                  - key: failure-domain.beta.kubernetes.io/region
              +                    operator: In
              +                    values:
              +                      - us-east-1
              +                  - key: failure-domain.beta.kubernetes.io/zone
              +                    operator: In
              +                    values:
              +                      - us-east-1a
              +          tolerations:
              +            - key: role
              +              operator: Equal
              +              value: scylla-clusters
              +              effect: NoSchedule
              +
              +
              +
              +
              +

              Settings Explanation

              +
              +

              Cluster Settings

              +
                +
              • version: The version of Scylla to use. It is used as the image tag to pull.

              • +
              • agentVersion: The version of Scylla Manager Agent to use. It is used as the image tag to pull.

              • +
              • repository: Optional field. Specifies a custom image repo. If left unset, the official docker hub repo is used (scylladb/scylla).

              • +
              • agentRepository: Optional field. Specifies a custom Scylla Manager Agent image repo. If left unset, the official docker hub repo is used (scylladb/scylla).

              • +
              • developerMode: Optional field. If it’s true, then Scylla is started in developer mode. This setting is for shared test/dev environments.

              • +
              • cpuset: Optional field. If it’s true, then the operator will start Scylla with cpu pinning for maximum performance. For this to work, you need to set the kubelet to use the static cpu policy and only specify limits in resources.

              • +
              • automaticOrphanedNodeCleanup: Optional field. Controls if automatic orphan node cleanup should be performed.

              • +
              • alternator: Optional field. Defines Alternator configuration.

                +
                  +
                • port: Port on which to bind to Alternator API.

                • +
                • writeIsolation: required Desired write isolation.

                • +
                +
              • +
              • genericUpgrade: Optional field. Defines GenericUpgrade configuration.

                +
                  +
                • failureStrategy: specifies which logic is executed when upgrade failure happens. Currently only Retry is supported.

                • +
                • pollInterval: specifies how often upgrade logic polls on state updates. +Increasing this value should lower number of requests sent to the kube-apiserver, but it may affect +overall time spent during upgrade.

                • +
                +
              • +
              • datacenter: Datacenter definition.

              • +
              • sysctls: Optional field. Sysctl properties to be applied during initialization.

              • +
              • scyllaArgs: Optional field. Command line argument passed to Scylla container image. Note: not all Scylla versions support it.

              • +
              • network: Optional field. Allows to customize network parameters.

                +
                  +
                • hostNetworking: controls if host networking should be enabled.

                • +
                • dnsPolicy: controls Scylla Pod DNS Policy. See details.

                • +
                +
              • +
              • repairs: Optional field. Repair tasks definitions. See Scylla Manager settings for details.

              • +
              • backups: Optional field. Repair tasks definitions. See Scylla Manager settings for details.

              • +
              +

              In the Scylla model, each cluster contains datacenters and each datacenter contains racks. At the moment, the operator only supports single datacenter setups.

              +
              +
              +

              Scylla Manager settings

              +

              Tasks are scheduled only when Scylla Manager is deployed in K8s cluster.

              +

              Repairs:

              +
                +
              • name - required - human readable name of the task. It must be unique across all tasks.

              • +
              • startDate - specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, +valid units are d, h, m, s (default “now”).

              • +
              • interval - Optional field. Task schedule interval e.g. 3d2h10m, valid units are d, h, m, s (default “0”).

              • +
              • numRetries - Optional field. The number of times a scheduled task will retry to run before failing (default 3).

              • +
              • dc - Optional field. A list of datacenter glob patterns, e.g. ["dc1", "!otherdc*"] used to specify the DCs to include or exclude from backup.

              • +
              • failFast - Optional field. Stop repair on first error.

              • +
              • intensity - Optional field. Specifies how many token ranges (per shard) to repair in a single Scylla repair job. By default this is 1. +If you set it to 0 the number of token ranges is adjusted to the maximum supported by node (see max_repair_ranges_in_parallel in Scylla logs). +Valid values are 0 and integers >= 1. Higher values will result in increased cluster load and slightly faster repairs. +Changing the intensity impacts repair granularity if you need to resume it, the higher the value the more work on resume. +For Scylla clusters that do not support row-level repair, intensity can be a decimal between (0,1). +In that case it specifies percent of shards that can be repaired in parallel on a repair master node. +For Scylla clusters that are row-level repair enabled, setting intensity below 1 has the same effect as setting intensity 1. +Intensity is a number passed as string due to lack of support for float values in k8s controller runtime

              • +
              • parallel - Optional field. Specifies the maximum number of Scylla repair jobs that can run at the same time (on different token ranges and replicas). +Each node can take part in at most one repair at any given moment. By default the maximum possible parallelism is used. +The effective parallelism depends on a keyspace replication factor (RF) and the number of nodes. +The formula to calculate it is as follows: number of nodes / RF, ex. for 6 node cluster with RF=3 the maximum parallelism is 2.

              • +
              • keyspace - Optional field. A list of keyspace/tables glob patterns, e.g. ["keyspace", "!keyspace.table_prefix_*"] +used to include or exclude keyspaces from repair.

              • +
              • smallTableThreshold - Optional field. Enable small table optimization for tables of size lower than given threshold. +Supported units [B, MiB, GiB, TiB] (default "1GiB").

              • +
              +

              Backups:

              +
                +
              • name - required - human readable name of the task. It must be unique across all tasks.

              • +
              • startDate - Optional field. Specifies the task start date expressed in the RFC3339 format or now[+duration], e.g. now+3d2h10m, +valid units are d, h, m, s (default “now”).

              • +
              • interval - Optional field. task schedule interval e.g. 3d2h10m, valid units are d, h, m, s (default “0”).

              • +
              • numRetries - Optional field. the number of times a scheduled task will retry to run before failing (default 3).

              • +
              • dc - Optional field. A list of datacenter glob patterns, e.g. ["dc1","!otherdc*"] used to specify the DCs to include or exclude from backup.

              • +
              • keyspace - Optional field. A list of keyspace/tables glob patterns, e.g. ["keyspace","!keyspace.table_prefix_*"] used to include or exclude keyspaces from backup.

              • +
              • location - Optional field. A list of backup locations in the format [<dc>:]<provider>:<name> ex. s3:my-bucket. +The <dc>: part is optional and is only needed when different datacenters are being used to upload data to different locations. +<name> Optional field. must be an alphanumeric string and may contain a dash and or a dot, but other characters are forbidden. +The only supported storage at the moment are s3 and gcs.

              • +
              • rateLimit - Optional field. A list of megabytes (MiB) per second rate limits expressed in the format [<dc>:]<limit>. +The <dc>: part is optional and only needed when different datacenters need different upload limits. +Set to 0 for no limit (default 100).

              • +
              • retention - Optional field. The number of backups which are to be stored (default 3).

              • +
              • snapshotParallel - Optional field. A list of snapshot parallelism limits in the format [<dc>:]<limit>. +The <dc>: part is optional and allows for specifying different limits in selected datacenters. +If The <dc>: part is not set, the limit is global (e.g. ["dc1:2,5"]) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters.

              • +
              • uploadParallel - Optional field. A list of upload parallelism limits in the format [<dc>:]<limit>. +The <dc>: part is optional and allows for specifying different limits in selected datacenters. +If The <dc>: part is not set the limit is global (e.g. ["dc1:2,5"]) the runs are parallel in n nodes (2 in dc1) +and n nodes in all the other datacenters.

              • +
              +
              +
              +

              Datacenter Settings

              +
                +
              • name: Name of the datacenter. Usually, a datacenter corresponds to a region.

              • +
              • racks: List of racks for the specific datacenter.

              • +
              +
              +
              +

              Rack Settings

              +
                +
              • name: Name of the rack. Usually, a rack corresponds to an availability zone.

              • +
              • members: Number of Scylla members for the specific rack. (In Scylla documentation, they are called nodes. We don’t call them nodes to avoid confusion as a Scylla Node corresponds to a Kubernetes Pod, not a Kubernetes Node).

              • +
              • storage: Defines the specs of the underlying storage.

                +
                  +
                • capacity: Capacity of the PersistentVolume to request.

                • +
                • storageClassName: Optional field. StorageClass of PersistentVolume to request.

                • +
                +
              • +
              • resources: Defines the CPU and RAM resources for the Scylla Pods.

                +
                  +
                • requests: The minimum amount of resources needed to run a Scylla container.

                  +
                    +
                  • cpu: CPU requests.

                  • +
                  • memory: RAM requests.

                  • +
                  +
                • +
                • limits: The maximum amount of resources that can be used by a Scylla container.

                  +
                    +
                  • cpu: CPU limits.

                  • +
                  • memory: RAM limits.

                  • +
                  +
                • +
                +
              • +
              • agentResources: Optional field. Defines the CPU and RAM resources for the Scylla Manager Agent container. See resources for details.

              • +
              • volumes: Optional field. Defines volumes available in Scylla Pod. See details.

              • +
              • volumeMounts: Optional field. Defines which volumes will be attached to Scylla container.

              • +
              • agentVolumeMounts: Optional field. Defines which volumes will be attached to Agent container.

              • +
              • scyllaConfig: Optional field. name of custom config map which will be merged with Scylla config.

              • +
              • scyllaAgentConfig: Optional field. name of custom secret which will be merged with Scylla Manager Agent config.

              • +
              • placement: Optional field. Defines the placement of Scylla Pods. Has the following subfields:

                + +
              • +
              +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/search.html b/v1.9/search.html new file mode 100644 index 00000000000..30d6ec7347a --- /dev/null +++ b/v1.9/search.html @@ -0,0 +1,546 @@ + + + + + + + + + + + + + Search | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + + + +
              + + + + + +
              + + +
              + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file diff --git a/v1.9/searchindex.js b/v1.9/searchindex.js new file mode 100644 index 00000000000..a82981e0d24 --- /dev/null +++ b/v1.9/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["contributing", "eks", "generic", "gke", "helm", "index", "known_issues", "manager", "migration", "monitoring", "nodeoperations/automatic_cleanup", "nodeoperations/index", "nodeoperations/maintenance_mode", "nodeoperations/replace_node", "nodeoperations/restore", "nodeoperations/scylla_upgrade", "performance", "releases", "scylla_cluster_crd", "upgrade"], "filenames": ["contributing.md", "eks.md", "generic.md", "gke.md", "helm.md", "index.rst", "known_issues.md", "manager.md", "migration.md", "monitoring.md", "nodeoperations/automatic_cleanup.md", "nodeoperations/index.rst", "nodeoperations/maintenance_mode.md", "nodeoperations/replace_node.md", "nodeoperations/restore.md", "nodeoperations/scylla_upgrade.md", "performance.md", "releases.md", "scylla_cluster_crd.md", "upgrade.md"], "titles": ["Contributing to Scylla Operator", "Deploying Scylla on EKS", "Deploying Scylla on a Kubernetes Cluster", "Deploying Scylla on GKE", "Deploying Scylla stack using Helm Charts", "Scylla Operator Documentation", "Known issues", "Deploying Scylla Manager on a Kubernetes Cluster", "Version migrations", "Monitoring", "Automatic cleanup and replacement in case when k8s node is lost", "Node operations using Scylla Operator", "Maintenance mode", "Replacing a Scylla node", "Restore from backup", "Upgrading version of Scylla", "Performance tuning", "Releases", "Scylla Cluster CRD", "Upgrade of Scylla Operator"], "terms": {"To": [0, 2, 3, 4, 6, 7, 8, 9, 12, 13, 14, 15, 19], "environ": [0, 2, 4, 8, 18], "must": [0, 2, 7, 13, 15, 16, 17, 18, 19], "have": [0, 1, 2, 3, 4, 7, 8, 9, 14, 15, 16, 19], "follow": [0, 1, 2, 3, 4, 6, 7, 8, 14, 15, 17, 18, 19], "go": [0, 2, 3, 4, 8, 13, 19], "1": [0, 1, 2, 4, 7, 8, 9, 13, 14, 15, 16, 17, 18], "13": [0, 7, 14], "make": [0, 1, 2, 3, 4, 7, 8, 9, 13, 17, 19], "sure": [0, 2, 3, 4, 7, 8, 13, 17, 19], "gopath": 0, "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19], "set": [0, 1, 4, 5, 6, 7, 9, 14, 15, 16], "home": 0, "kustom": 0, "v3": 0, "0": [0, 2, 3, 4, 7, 9, 13, 14, 15, 17, 18], "kubebuild": 0, "v2": 0, "3": [0, 1, 2, 4, 7, 14, 15, 16, 17, 18], "docker": [0, 2, 4, 17, 18, 19], "git": [0, 2, 8, 17, 19], "client": [0, 2, 4, 8, 9, 13], "instal": [0, 2, 5, 7, 8, 9, 19], "github": [0, 2, 5, 9, 17], "account": [0, 3], "all": [0, 1, 2, 3, 4, 7, 8, 9, 14, 15, 16, 18], "depend": [0, 3, 8, 12, 13, 14, 16, 17, 18], "dep": 0, "simpli": [0, 2, 4, 8, 12, 14, 15], "run": [0, 1, 3, 4, 5, 7, 8, 9, 13, 15, 16, 18, 19], "sh": [0, 1, 3], "from": [0, 1, 2, 3, 4, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19], "browser": 0, "navig": 0, "http": [0, 1, 2, 4, 7, 9, 19], "com": [0, 1, 2, 3, 4, 8, 9, 16, 18, 19], "scylladb": [0, 2, 3, 4, 8, 9, 16, 17, 18, 19], "click": 0, "button": 0, "open": [0, 2, 5, 7], "consol": 0, "window": 0, "do": [0, 2, 7, 9, 12, 18, 19], "repo": [0, 4, 8, 18, 19], "path": [0, 2, 8, 14, 19], "mkdir": [0, 14], "p": [0, 3, 8, 14, 15, 19], "src": 0, "local": [0, 9, 13, 18], "cd": [0, 1, 2, 3, 14], "where": [0, 1, 3, 8, 14, 15], "user": [0, 2, 3, 5, 7, 8, 9, 12, 14, 15, 16, 18, 19], "name": [0, 1, 2, 4, 7, 8, 9, 13, 14, 15, 16, 18, 19], "first": [0, 1, 2, 3, 4, 7, 8, 9, 14, 15, 18, 19], "you": [0, 1, 2, 3, 4, 7, 8, 9, 13, 14, 15, 18, 19], "need": [0, 2, 3, 4, 8, 9, 13, 14, 15, 16, 18, 19], "list": [0, 2, 3, 7, 8, 14, 18, 19], "verifi": [0, 2, 13], "wa": [0, 2, 4, 7, 8, 13, 14, 19], "ad": [0, 2, 5], "v": 0, "now": [0, 1, 2, 3, 7, 8, 18], "should": [0, 2, 4, 7, 8, 9, 13, 15, 16, 18], "least": [0, 3, 4, 16], "origin": 0, "can": [0, 1, 2, 3, 4, 7, 8, 9, 13, 14, 15, 16, 18], "also": [0, 1, 2, 3, 4, 5, 7, 8, 9], "other": [0, 3, 4, 7, 9, 13, 16, 17, 18], "collabor": 0, "contributor": 0, "featur": [0, 3, 16], "bug": [0, 17], "fix": [0, 6, 17], "pr": 0, "us": [0, 1, 2, 3, 5, 7, 8, 13, 14, 15, 16, 17, 18, 19], "makefil": 0, "command": [0, 1, 2, 3, 4, 6, 7, 8, 9, 13, 14, 18], "chang": [0, 2, 3, 4, 7, 8, 9, 15, 18, 19], "img": 0, "variabl": 0, "repositori": [0, 2, 18, 19], "access": [0, 7], "push": 0, "wait": [0, 2, 4, 8, 15, 19], "imag": [0, 3, 8, 15, 16, 17, 18, 19], "built": 0, "upload": [0, 18], "new": [0, 2, 3, 5, 7, 8, 9, 13, 15, 16, 17, 19], "base": [0, 4, 16], "start": [0, 1, 2, 7, 14, 15, 16, 18], "work": [0, 1, 3, 4, 8, 14, 16, 17, 18], "ensur": [0, 8], "ar": [0, 1, 2, 3, 4, 7, 8, 9, 13, 15, 16, 17, 18, 19], "up": [0, 1, 3, 4, 5, 8, 9, 13, 14, 15, 16, 19], "date": [0, 4, 7, 17, 18, 19], "latest": [0, 1, 5, 17], "fetch": 0, "off": [0, 2, 12, 15, 17, 19], "master": [0, 17, 18], "give": [0, 2, 3, 7, 17], "simpl": [0, 2, 4, 7, 8, 12, 13, 14, 15, 18, 19], "descript": [0, 4], "gener": [0, 1, 2, 3, 7, 8, 9, 15, 19], "two": [0, 4, 7, 8, 15, 16, 19], "three": [0, 4, 7], "word": 0, "separ": [0, 1, 3, 8, 16], "dash": [0, 18], "without": [0, 3, 4, 9], "number": [0, 2, 18, 19], "checkout": [0, 8, 19], "b": [0, 3, 12, 18], "readi": [0, 2, 4, 7, 8, 12, 13, 15, 19], "dure": [0, 15, 18, 19], "lifecycl": 0, "keep": [0, 1, 3], "As": [0, 1, 3, 7], "team": 0, "rebas": 0, "top": 0, "thi": [0, 1, 2, 3, 4, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19], "avoid": [0, 18], "unnecessari": 0, "merg": [0, 15, 17, 18], "clean": [0, 14], "whenev": 0, "never": [0, 19], "want": [0, 1, 2, 3, 4, 7, 14, 19], "alwai": [0, 2, 12, 16], "otherwis": [0, 9, 17], "end": [0, 8, 9, 17], "If": [0, 1, 2, 3, 4, 6, 7, 8, 9, 15, 18], "ani": [0, 3, 4, 8, 14, 16, 17, 18], "modifi": [0, 3, 15], "file": [0, 2, 3, 4, 8, 14, 19], "stash": 0, "them": [0, 1, 2, 3, 4, 8, 9, 16, 18, 19], "save": [0, 2, 8, 14, 15, 19], "u": [0, 1, 2, 3, 4, 7, 8, 12, 13, 14, 15, 16, 18], "some": [0, 2, 4, 7, 13, 14, 17], "veri": [0, 4, 8, 19], "power": [0, 16], "understand": [0, 8], "how": [0, 1, 3, 4, 7, 9, 13, 14, 18], "els": [0, 9], "risk": 0, "lose": [0, 10], "read": [0, 4, 8], "about": [0, 2, 4, 16], "document": [0, 2, 4, 7, 18], "well": [0, 2, 7, 8, 9], "worth": 0, "In": [0, 2, 3, 4, 7, 8, 9, 10, 13, 15, 16, 18, 19], "nutshel": 0, "doe": [0, 2, 4, 7], "unwind": 0, "remov": [0, 2, 4, 8, 10, 12, 15, 19], "temporarili": 0, "The": [0, 2, 3, 5, 6, 7, 9, 14, 16, 17, 18], "re": [0, 8, 19], "appli": [0, 1, 2, 3, 4, 6, 7, 8, 9, 16, 18, 19], "one": [0, 2, 4, 7, 8, 10, 13, 14, 15, 18, 19], "conflict": 0, "prompt": 0, "befor": [0, 8, 9, 14, 15, 17, 18, 19], "continu": [0, 15], "output": [0, 2, 7, 8, 14], "close": [0, 4], "It": [0, 1, 2, 3, 4, 15, 18], "tell": 0, "complet": [0, 2, 9, 13], "when": [0, 2, 7, 8, 9, 11, 12, 15, 16, 17, 18], "done": [0, 1, 2, 3, 7], "see": [0, 1, 2, 3, 4, 5, 7, 8, 9, 16, 18], "onc": [0, 1, 2, 3, 4, 7, 14, 15, 19], "implement": 0, "unit": [0, 18], "test": [0, 7, 9, 17, 18], "pass": [0, 3, 14, 17, 18], "integr": [0, 5], "order": [0, 2, 3, 7, 19], "requir": [0, 2, 6, 16, 17, 18, 19], "again": [0, 8, 9, 12], "prepar": 0, "minim": [0, 4], "logic": [0, 3, 18], "so": [0, 2, 3, 4, 9, 16, 19], "we": [0, 1, 2, 3, 4, 7, 8, 9, 13, 14, 16, 17, 18, 19], "maintain": [0, 17], "most": [0, 1, 2, 3, 4, 9, 16, 18], "commonli": 0, "includ": [0, 4, 18], "singl": [0, 4, 7, 14, 18], "squash": 0, "although": [0, 4, 8, 9], "sometim": [0, 2], "multipl": [0, 2, 7, 8], "inspect": 0, "determin": 0, "log": [0, 2, 7, 15, 18], "edit": [0, 1, 2, 3, 7], "even": [0, 15], "reorder": 0, "exampl": [0, 1, 2, 3, 4, 7, 8, 9, 12, 14, 15, 16, 19], "last": 0, "5": [0, 7, 14, 15, 16, 17, 18], "tool": [0, 9, 14], "head": 0, "pleas": [0, 4, 16, 18, 19], "line": [0, 14, 18], "summari": 0, "would": [0, 2, 7, 13], "like": [0, 2, 5, 7, 8, 9, 13, 16, 17], "prefix": 0, "relev": 0, "directori": [0, 14, 19], "colon": 0, "changelog": 0, "get": [0, 1, 2, 3, 4, 7, 8, 9, 13, 14, 15, 19], "made": [0, 17], "look": [0, 2, 4, 8], "just": [0, 1, 2, 3], "good": [0, 4], "more": [0, 2, 3, 4, 9, 13, 16, 18], "sai": 0, "enter": [0, 4, 13, 15], "blank": 0, "carri": 0, "rememb": [0, 2], "why": 0, "itself": [0, 4, 7, 12], "show": [0, 2, 15, 17], "what": [0, 2, 4, 7, 8, 9, 15], "write": [0, 2, 18], "better": [0, 3], "than": [0, 2, 8, 13, 18], "less": [0, 8, 9, 19], "compar": [0, 8], "behaviour": 0, "after": [0, 1, 2, 3, 4, 7, 13], "imagin": 0, "yourself": 0, "12": [0, 7, 14, 17], "month": 0, "time": [0, 4, 7, 8, 13, 14, 17, 18], "ve": 0, "forgotten": 0, "everyth": [0, 1, 2, 3, 4, 15], "did": 0, "speed": 0, "quickli": 0, "an": [0, 2, 4, 5, 15, 16, 17, 18, 19], "issu": [0, 5, 7, 8, 15, 19], "1234": 0, "subject": [0, 16], "fit": 0, "don": [0, 1, 3, 4, 18], "t": [0, 1, 2, 3, 4, 7, 8, 13, 14, 16, 17, 18, 19], "associ": [0, 2, 7, 8], "put": 0, "link": [0, 6], "here": [0, 2, 19], "short": [0, 8], "sidecar": [0, 2, 4, 8, 19], "reconcil": [0, 9], "loop": 0, "And": [0, 4], "longer": [0, 2, 3, 13], "api": [0, 2, 7, 9, 17, 18], "support": [0, 2, 4, 5, 7, 15, 18, 19], "host": [0, 7, 9, 13, 14, 18], "network": [0, 13, 16, 18], "crd": [0, 2, 4, 5, 7, 8, 16, 19], "ha": [0, 2, 3, 17, 18], "properti": [0, 2, 18], "select": [0, 18], "apropri": 0, "dn": [0, 2, 9, 12, 13, 18], "polici": [0, 1, 3, 4, 16, 18], "recent": 0, "obviou": 0, "tab": 0, "track": [0, 2, 7], "automat": [0, 2, 3, 7, 11, 17, 18, 19], "guid": [1, 2, 3, 4, 7, 8, 18, 19], "focus": [1, 3], "improv": 1, "perform": [1, 2, 3, 5, 10, 18], "trick": 1, "won": [1, 16], "differ": [1, 2, 4, 7, 16, 18], "machin": [1, 2, 3, 9], "tier": 1, "kubelet": [1, 3, 16, 18], "node": [1, 2, 3, 4, 5, 7, 8, 9, 12, 15, 18], "static": [1, 3, 8, 16, 18], "cpu": [1, 2, 3, 4, 16, 18], "sdd": [1, 3], "disk": [1, 2, 3, 13, 16, 18], "raid0": [1, 3], "maximum": [1, 3, 18], "same": [1, 2, 3, 4, 7, 8, 15, 16, 17, 18], "tri": [1, 3], "step": [1, 2, 3, 4, 7, 8, 9, 19], "accord": [1, 2, 3, 8, 15], "your": [1, 2, 3, 4, 6, 7, 8, 9, 10, 13, 14, 15, 16, 19], "prefer": [1, 3], "eks_region": 1, "east": [1, 2, 4, 7, 8, 13, 14, 15, 16, 18], "eks_zon": 1, "1a": [1, 2, 7, 8, 13, 14, 15, 16, 18], "1b": [1, 4], "1c": 1, "insid": [1, 2, 3, 12], "folder": [1, 3], "z": [1, 3, 17], "r": 1, "benchmark": [1, 3], "cassandra": [1, 3], "stress": [1, 3], "export": [1, 3], "option": [1, 2, 3, 4, 7, 16, 18], "own": [1, 3, 4, 13], "cluster_nam": [1, 2, 3], "demo": [1, 3, 13], "For": [1, 2, 4, 5, 7, 8, 9, 12, 14, 16, 18], "ll": [1, 3], "A": [1, 2, 3, 4, 9, 18, 19], "nodegroup": 1, "i3": 1, "2xlarg": 1, "pod": [1, 2, 3, 4, 7, 8, 9, 10, 12, 13, 14, 15, 16, 18], "These": [1, 3, 16, 19], "onli": [1, 2, 3, 8, 15, 16, 17, 18, 19], "accept": [1, 17], "toler": [1, 18], "pool": [1, 3, 13, 16], "instancetyp": 1, "desiredcapac": 1, "label": [1, 2, 3, 9, 12, 13, 16], "taint": [1, 3], "role": [1, 2, 3, 8, 18], "noschedul": [1, 3, 18], "ssh": [1, 6, 7], "allow": [1, 2, 4, 9, 12, 15, 16, 18], "true": [1, 2, 3, 4, 7, 9, 18, 19], "kubeletextraconfig": 1, "cpumanagerpolici": [1, 3], "4": [1, 2, 3, 4, 7, 15, 16, 17], "c4": 1, "later": [1, 3], "larg": 1, "monitor": [1, 3, 5, 17], "stack": [1, 3, 5, 9], "sever": 1, "helm": [1, 2, 5, 9, 17], "doc": [1, 2, 3, 16], "_": [1, 2, 6, 18], "eksctl": 1, "aw": [1, 14], "amazon": 1, "userguid": 1, "html": 1, "kubectl": [1, 2, 3, 4, 7, 8, 9, 12, 13, 14, 15, 16], "kubernet": [1, 4, 5, 8, 9, 17, 18], "io": [1, 2, 9, 17, 18, 19], "task": [1, 2, 5, 18], "volum": [1, 3, 18], "which": [1, 2, 3, 4, 5, 7, 8, 10, 13, 14, 15, 16, 18, 19], "discov": [1, 3], "mount": [1, 2, 3], "point": [1, 3, 8, 9, 15], "avail": [1, 2, 3, 4, 7, 9, 13, 14, 15, 16, 18, 19], "persistentvolum": [1, 2, 3, 18], "common": [1, 2, 3, 4, 7, 8, 16, 19], "optim": [1, 16, 18], "f": [1, 2, 3, 4, 7, 8, 9, 14, 19], "yaml": [1, 2, 3, 4, 7, 8, 9, 19], "launch": [1, 3], "highli": [1, 3], "instruct": [1, 2, 3, 4, 8, 18], "found": [1, 2, 3], "experi": [1, 3], "mean": [2, 8], "ideal": 2, "best": [2, 3], "fast": 2, "direct": [2, 9], "extra": 2, "setup": [2, 9, 18], "platform": [2, 9], "specif": [2, 4, 14, 16, 18, 19], "check": [2, 5, 7, 8, 13, 15, 16, 19], "detail": [2, 7, 9, 16, 18], "particular": [2, 4, 15, 17], "gke": [2, 5, 13], "storag": [2, 3, 4, 9, 16, 18, 19], "class": [2, 16], "provis": [2, 3, 4], "enabl": [2, 3, 6, 7, 10, 12, 15, 18], "stabl": [2, 4, 19], "daunt": 2, "error": [2, 3, 7, 15, 18], "prone": 2, "fortun": 2, "wai": [2, 3, 7, 8, 9], "life": [2, 13], "easier": [2, 8, 9, 19], "minikub": [2, 4], "breez": 2, "littl": 2, "bit": [2, 4], "resourc": [2, 5, 7, 8, 9, 10, 16, 18, 19], "default": [2, 3, 4, 6, 7, 13, 16, 18], "6": [2, 16, 17, 18], "Then": [2, 3, 4, 15], "awar": 2, "eval": 2, "env": 2, "manifest": [2, 19], "clone": 2, "either": [2, 4, 7], "upsteam": [2, 4], "self": [2, 4], "sign": [2, 4, 8], "certif": [2, 4, 9], "": [2, 3, 4, 7, 8, 9, 13, 14, 16, 18, 19], "until": [2, 4, 8, 15, 19], "condit": [2, 4, 8, 9, 16, 19], "establish": [2, 19], "issuer": 2, "n": [2, 4, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19], "rollout": [2, 8, 9, 19], "statu": [2, 4, 5, 7, 8, 9, 13, 14, 15, 19], "deploy": [2, 4, 7, 9, 14, 15, 18, 19], "app": [2, 4, 9, 14, 15, 19], "webhook": [2, 19], "namespac": [2, 4, 7, 8, 16, 18, 19], "scyllaclust": [2, 4, 8, 9, 10, 14, 15, 16, 18, 19], "instanc": [2, 3, 4, 7, 8, 9], "valu": [2, 3, 4, 8, 15, 18], "feel": 2, "free": [2, 3], "brows": 2, "tweak": 2, "full": [2, 7, 8, 13, 15, 18], "object": [2, 9, 19], "been": 2, "repres": 2, "our": [2, 3, 8, 16, 17, 19], "below": [2, 7, 8, 9, 16, 18], "import": [2, 3, 14, 17], "becaus": [2, 7, 13], "successfulli": [2, 9], "extend": 2, "citizen": 2, "cloud": [2, 7, 9], "nativ": 2, "easi": 2, "someth": [2, 7, 12], "restart": [2, 4, 7, 8, 13, 15, 19], "ag": [2, 4, 7, 8, 13, 19], "2": [2, 3, 4, 7, 8, 12, 13, 14, 15, 16, 17, 18], "9m49": 2, "7m43": 2, "6m46": 2, "note": [2, 3, 7, 9, 18, 19], "pattern": [2, 4, 18], "datacenter_nam": 2, "rack_nam": 2, "instance_numb": 2, "specifi": [2, 4, 18], "abov": [2, 4, 7, 9, 19], "datacent": [2, 4, 7, 13, 16], "rack": [2, 4, 5, 7, 13, 15, 16], "attach": [2, 3, 8, 13, 18], "pick": 2, "resembl": 2, "find": [2, 4, 9, 14, 15, 19], "servic": [2, 4, 8, 9, 12, 13], "inconsequenti": 2, "thei": [2, 7, 18], "anyth": 2, "desir": [2, 4, 7, 15, 18], "member": [2, 4, 7, 8, 15, 16, 18], "entri": 2, "l": [2, 4, 7, 8, 9, 14], "state": [2, 4, 7, 9, 13, 15, 18], "its": [2, 7, 8], "current": [2, 4, 5, 9, 15, 18], "describ": [2, 7, 8, 14, 15, 19], "squeez": 2, "out": [2, 5, 8, 14, 15, 19], "necessari": [2, 3, 9], "emploi": 2, "version": [2, 3, 4, 5, 7, 9, 11, 16, 17, 18, 19], "agentvers": [2, 16, 18], "cpuset": [2, 18], "hostnetwork": [2, 18], "result": [2, 8, 18], "defin": [2, 4, 7, 18], "sysctl": [2, 18], "kei": [2, 7, 18], "pair": 2, "increas": [2, 18], "event": 2, "asynchron": 2, "process": [2, 3, 12, 15, 16, 19], "linux": 2, "aio": 2, "max": [2, 18], "nr": 2, "spec": [2, 4, 7, 8, 9, 15, 16, 18, 19], "2097152": 2, "capabl": 2, "instead": 2, "regular": [2, 7], "small": [2, 7, 18], "definit": [2, 3, 4, 5, 7, 8, 15, 18, 19], "developermod": [2, 18], "port": [2, 4, 8, 9, 13, 18, 19], "8000": 2, "writeisol": [2, 18], "only_rmw_uses_lwt": 2, "whichev": 2, "provid": [2, 3, 4, 9, 16, 18], "isol": [2, 18], "forbid": 2, "rmw": 2, "lwt": 2, "between": [2, 18], "those": [2, 16], "level": [2, 7, 18], "cql": [2, 7, 14], "pure": 2, "alien": 2, "cqlsh": [2, 14], "shell": [2, 8], "exec": [2, 7, 13, 14], "keyspac": [2, 7, 14, 15, 18], "convent": 2, "connect": [2, 7], "python": [2, 16], "driver": 2, "svc": [2, 7, 8, 9, 12, 13, 14], "session": 2, "plain": 2, "take": [2, 13, 14, 15, 16, 18], "configmap": 2, "refer": [2, 4, 8, 9, 17, 18, 19], "call": [2, 3, 14, 16, 18, 19], "rest": [2, 7], "config": [2, 3, 7, 18], "propag": [2, 8], "statefulset": [2, 4, 8, 9, 15, 19], "rackdc": 2, "tmp": [2, 14], "o": [2, 8, 9, 17], "dry": 2, "replac": [2, 5, 8, 9, 11, 19], "overrid": 2, "prefer_loc": 2, "dc_suffix": 2, "second": [2, 18], "each": [2, 3, 4, 7, 8, 14, 15, 16, 18, 19], "serv": [2, 4, 9], "main": [2, 4, 7], "endpoint": 2, "interact": [2, 12], "variou": 2, "thing": 2, "secur": 2, "backup": [2, 5, 7, 11, 18, 19], "secret": [2, 4, 9, 18], "popul": 2, "content": [2, 3, 4, 14, 17], "copi": [2, 14], "auto": 2, "empti": [2, 14], "being": [2, 7, 12, 13, 15, 17, 18], "decod": 2, "roll": [2, 4, 5, 8, 15, 19], "prometheu": [2, 4, 5, 7], "grafana": [2, 5], "addit": [2, 4, 7, 8, 19], "field": [2, 4, 9, 15, 18], "add": [2, 4, 7, 8, 12, 13, 19], "append": 2, "choos": [2, 5, 11], "inform": [2, 9, 15], "happen": [2, 15, 18], "along": 2, "mini": 2, "cli": [2, 4, 7, 14], "job": [2, 17, 18], "against": 2, "doesn": [2, 3, 19], "core": [2, 3, 16], "count": [2, 3, 7], "10": [2, 4, 7, 8, 13, 17], "50": [2, 18], "000": 2, "throttl": [2, 16], "throughput": 2, "30": 2, "op": [2, 8], "sec": 2, "total": 2, "300": 2, "hack": 2, "cass": 2, "gen": 2, "py": 2, "num": [2, 3, 7], "memori": [2, 4, 16, 18], "20g": 2, "50000000": 2, "limit": [2, 4, 7, 16, 18], "30000": 2, "script": [2, 3, 16], "proper": 2, "argument": [2, 7, 18], "case": [2, 8, 13, 16, 18, 19], "alter": 2, "h": [2, 18], "usag": 2, "num_job": 2, "scylla_vers": 2, "thread": 2, "per": [2, 18], "connections_per_host": 2, "print": [2, 14, 15], "stdout": 2, "nodeselector": [2, 16], "templat": [2, 8, 9, 19], "help": [2, 5], "messag": [2, 7, 15], "exit": 2, "server": [2, 3, 7, 9, 19], "ip": [2, 4, 6, 8, 9, 13], "gb": 2, "ie": 2, "2g": 2, "10000000": 2, "rate": [2, 18], "certain": 2, "selector": [2, 19], "eg": 2, "while": [2, 3], "metric": [2, 4], "finish": [2, 14], "delet": [2, 7, 8, 13, 15, 19], "walk": [2, 18], "through": [2, 4, 18], "destroi": [2, 7], "data": [2, 3, 7, 9, 13, 14, 15, 18, 19], "come": [2, 7, 16], "examin": [2, 7], "ok": 2, "persist": [3, 7], "guarante": [3, 16], "gcp_user": 3, "gcloud": 3, "format": [3, 7, 15, 18], "gcp_project": 3, "project": [3, 5], "gcp_zone": 3, "west1": 3, "yanniszark": 3, "arrikto": 3, "226716": 3, "warn": 3, "zone": [3, 5, 18], "ex": [3, 18], "region": [3, 18], "gcp_region": 3, "cluster_vers": 3, "contain": [3, 4, 8, 14, 15, 17, 18, 19], "validmastervers": 3, "manag": [3, 5, 8, 13, 14, 16, 17, 19], "systemconfig": 3, "kubeletconfig": 3, "nodepool": 3, "n1": 3, "standard": 3, "8": [3, 7, 9, 17, 18], "capac": [3, 4, 16, 18], "purpos": 3, "type": [3, 4, 8, 9, 13, 15, 16, 17], "pd": 3, "ssd": 3, "size": [3, 13, 14, 18], "20": [3, 7, 17], "ubuntu_containerd": 3, "system": [3, 8, 15, 19], "stackdriv": 3, "autoupgrad": 3, "autorepair": 3, "32": 3, "combin": 3, "arrai": 3, "beta": [3, 17, 18], "ephemer": 3, "disabl": [3, 4, 6, 12, 15], "upgrad": [3, 4, 5, 8, 11, 17, 18], "repair": [3, 5, 7, 13, 18], "hard": 3, "timeout": [3, 4, 7, 8, 9], "respect": 3, "pdb": 3, "forc": 3, "comput": 3, "At": [3, 8, 15, 18], "handl": 3, "manual": [3, 8, 9, 15, 19], "control": [3, 7, 8, 9, 14, 15, 18, 19], "over": [3, 13, 15], "By": [3, 4, 16, 18], "rbac": 3, "permiss": [3, 7, 8], "credenti": [3, 7, 9, 14], "clusterrolebind": 3, "easiest": 3, "obtain": 3, "gcp": 3, "iam": 3, "web": 3, "interfac": 3, "bind": [3, 18], "clusterrol": [3, 8], "binari": 3, "distro": 3, "convert": 3, "filesystem": [3, 12], "taken": [3, 14, 15], "care": 3, "unfortun": 3, "abl": [3, 4], "ext4": 3, "prevent": 3, "reformat": 3, "back": [3, 12, 13, 15], "despit": 3, "effort": 3, "solut": 3, "workaround": 3, "Its": 3, "robust": 3, "remain": 3, "unchang": 3, "afterward": 3, "sed": [3, 8, 19], "g": [3, 8, 18, 19], "inject": 3, "match": [3, 9, 16, 17], "compon": [4, 7, 9], "k8": [4, 5, 7, 8, 11, 12, 13, 16, 18], "cluster": [4, 5, 8, 9, 10, 12, 13, 14, 15, 16, 19], "could": 4, "16": [4, 7, 17], "googleapi": [4, 19], "updat": [4, 7, 9, 18, 19], "creat": [4, 7, 8, 9, 14, 16, 18, 19], "autogener": 4, "60": [4, 7], "execut": [4, 6, 7, 8, 14, 15, 16, 18], "search": 4, "v1": [4, 7, 9, 16, 17, 18], "hardwar": 4, "rewrit": 4, "ca": [4, 9], "autom": [4, 5, 7, 19], "databas": [4, 7, 18], "ma": 4, "reason": 4, "let": [4, 7, 14], "interest": 4, "customiz": 4, "sourc": [4, 5, 7, 19], "download": [4, 14], "hub": [4, 18], "pullpolici": 4, "fullfil": 4, "pull": [4, 18, 19], "url": 4, "compos": 4, "follw": 4, "tag": [4, 8, 15, 17, 18, 19], "ifnotpres": 4, "much": [4, 13], "alloc": 4, "via": 4, "100m": 4, "128mi": 4, "request": [4, 8, 9, 16, 18], "32mi": 4, "decid": [4, 17], "whether": [4, 16], "createselfsignedcertif": 4, "certificatesecretnam": 4, "overwrit": 4, "under": [4, 7, 12, 14, 15], "cours": 4, "scyllaimag": 4, "agentimag": 4, "agent": [4, 7, 18], "express": [4, 18], "5g": 4, "1gi": [4, 9], "gib": [4, 18], "customzi": 4, "consist": [4, 7, 16], "applic": [4, 16], "mani": [4, 9, 16, 18], "500m": 4, "500mi": 4, "similarli": 4, "controllerimag": 4, "controllerresourc": 4, "30mi": 4, "20mi": 4, "intern": [4, 7], "dedic": [4, 7, 16], "land": [4, 16], "bootstrap": [4, 13], "isn": 4, "valid": [4, 7, 9, 15, 18, 19], "correctli": 4, "5dbcb54f5c": 4, "vjm4m": 4, "51": [4, 13], "wfjbw": 4, "extern": [4, 8, 9, 13], "clusterip": [4, 8, 13], "105": 4, "207": 4, "130": 4, "none": [4, 8, 13], "443": [4, 9], "tcp": [4, 8, 13], "TO": 4, "replicaset": 4, "669db64dd": 4, "bcm4v": 4, "89": 4, "844ccc56c4": 4, "drbth": 4, "rhwqx": 4, "231": [4, 13], "53": [4, 7], "80": 4, "5090": 4, "9180": [4, 8, 13], "5m58": 4, "4m29": 4, "5m59": 4, "43": [4, 8, 13], "149": 4, "92": 4, "7000": [4, 8, 13], "7001": [4, 8, 13], "7199": [4, 8, 13], "10001": [4, 8, 13], "9042": [4, 8, 13], "9142": [4, 8, 13], "9160": [4, 8, 13], "49": 4, "exactli": [4, 17], "were": 4, "ask": 4, "spin": [4, 7], "servicemonitor": 4, "observ": [4, 15], "managg": 4, "both": 4, "fals": [4, 7, 9, 18], "notic": [4, 9], "prometh": 4, "scrape": 4, "uninstal": 4, "enterpris": [5, 7, 17], "deploi": [5, 18, 19], "relat": 5, "downscal": 5, "report": 5, "lesson": 5, "univers": 5, "multi": 5, "scale": [5, 15], "down": [5, 13], "dead": 5, "autoh": 5, "topic": [5, 11], "begin": [5, 15], "ek": 5, "chart": [5, 9, 17, 19], "tune": 5, "experiment": [5, 9, 16, 19], "procedur": [5, 13, 14, 15, 19], "releas": [5, 19], "known": 5, "custom": [5, 7, 9, 18], "contribut": 5, "fail": [6, 7, 9, 13, 18], "8th": 6, "migrat": [6, 19], "008": 6, "hairpin": 6, "On": [6, 16], "sudo": 6, "docker0": 6, "promisc": 6, "product": [7, 8, 9], "oper": [7, 8, 10, 12, 13, 14, 15, 16, 17, 18], "wide": 7, "predict": 7, "With": 7, "proprietari": 7, "softwar": 7, "licens": 7, "agreement": [7, 15], "spawn": 7, "mission": 7, "watch": 7, "synchron": 7, "regist": [7, 8, 14], "id": [7, 13, 14], "map": [7, 18], "reach": [7, 9, 15], "fulli": 7, "unschedul": [7, 10], "bare": [7, 9], "metal": [7, 9], "dc": [7, 18], "37m": 7, "28m": 7, "7bd9f968b9": 7, "w25jw": 7, "info": 7, "2020": [7, 14, 15, 17], "09": [7, 17], "23t11": 7, "25": [7, 8, 17], "27": [7, 17], "882z": 7, "m": [7, 18], "build_dat": 7, "commit": [7, 17], "built_bi": 7, "go_vers": 7, "loglevel": 7, "debug": 7, "apiaddress": 7, "127": 7, "5080": 7, "_trace_id": 7, "lqejv3kdr5gx9m3xq2ynnq": 7, "28": [7, 14], "435z": 7, "26": 7, "238z": 7, "20200816": 7, "76cc4dcc": 7, "pid": 7, "xqhkj0our8e6imdepm62hg": 7, "54": 7, "519z": 7, "tlscertfil": 7, "var": 7, "lib": 7, "scylla_manag": 7, "crt": [7, 9], "tlskeyfil": 7, "tlscafil": 7, "56090": 7, "prometheusscrapeinterv": 7, "5000000000": 7, "56112": 7, "logger": 7, "mode": [7, 11, 15, 18], "stderr": 7, "develop": [7, 9, 18], "ssl": [7, 9], "password": [7, 9, 14], "localdc": 7, "migratedir": 7, "etc": [7, 9, 16], "migratetimeout": 7, "30000000000": 7, "migratemaxwaitschemaagr": 7, "300000000000": 7, "replicationfactor": 7, "600000000": 7, "tokenawar": 7, "certfil": 7, "usercertfil": 7, "userkeyfil": 7, "healthcheck": 7, "250000000": 7, "ssltimeout": 7, "750000000": 7, "diskspacefreeminperc": 7, "agemax": 7, "43200000000000": 7, "segmentsperrepair": 7, "shardparallelmax": 7, "shardfailedsegmentsmax": 7, "100": [7, 18], "pollinterv": [7, 18], "200000000": 7, "errorbackoff": 7, "shardingignoremsbbit": 7, "config_fil": 7, "mnt": 7, "tutori": 7, "alreadi": [7, 9, 15], "d1d532cd": 7, "49f2": 7, "4c97": 7, "9263": 7, "25126532803b": 7, "talk": [7, 16], "sctool": [7, 14], "ti": [7, 13], "next": [7, 15], "400b2723": 7, "eec5": 7, "422a": 7, "b7f3": 7, "236a0e10575b": 7, "23": [7, 8], "sep": 7, "14": 7, "42": 7, "cest": 7, "15": 7, "healthcheck_rest": 7, "28169610": 7, "a969": 7, "4c20": 7, "9d11": 7, "ab7568b8a1bd": 7, "29": 7, "57": 7, "1m": 7, "recur": 7, "healhcheck": 7, "frontend": 7, "altern": [7, 9, 18], "prior": 7, "creation": [7, 17], "exist": [7, 8, 15, 17, 19], "interv": [7, 18], "1d": [7, 18], "weekli": [7, 18], "locat": [7, 14, 18], "s3": [7, 14, 18], "retent": [7, 18], "7d": [7, 18], "daili": [7, 18], "7": [7, 17], "configur": [7, 16, 18, 19], "consult": 7, "bucket": [7, 14, 18], "spot": 7, "275aae7f": 7, "c436": 7, "4fc8": 7, "bcec": 7, "479e65fb8372": 7, "58": 7, "d4946360": 7, "c29d": 7, "4bb4": 7, "8b9d": 7, "619ada495c2a": 7, "38": 7, "shortli": 7, "progress": [7, 9], "utc": 7, "durat": [7, 18], "69": 7, "system_auth": [7, 14], "06": [7, 17], "system_distribut": [7, 14], "00": 7, "system_trac": [7, 14], "present": 7, "my": [7, 18], "wasn": 7, "cannot": [7, 16], "due": [7, 10, 18], "lack": [7, 18], "target": [7, 16, 19], "62": [7, 13], "attempt": 7, "correct": [7, 9], "107": 7, "193": 7, "33": 7, "109": 7, "197": 7, "00000000": 7, "0000": 7, "000000000000": 7, "adhoc": 7, "retri": [7, 15, 18], "2b9dbe8c": 7, "9daa": 7, "4703": 7, "a66d": 7, "c29f63a917c8": 7, "infinit": 7, "resolv": [7, 15], "appear": 7, "kind": [8, 9, 16, 18, 19], "solv": [8, 19], "disambigu": [8, 19], "backward": [8, 19], "incompat": [8, 19], "involv": 8, "detach": 8, "scylla": [8, 9, 10, 12, 14, 16, 17], "period": 8, "noth": 8, "garbag": 8, "collect": [8, 9], "shouldn": [8, 13], "caus": [8, 12, 13, 15, 16], "downtim": 8, "consid": 8, "hacki": 8, "box": 8, "stage": [8, 15], "whole": [8, 15], "question": 8, "regard": 8, "welcom": 8, "slack": 8, "channel": 8, "sequenti": 8, "30m": [8, 19], "cert": 8, "anoth": 8, "offici": [8, 18], "websit": 8, "extract": [8, 14], "customresourcedefinit": [8, 19], "previou": [8, 15], "apivers": [8, 9, 16, 18, 19], "v1alpha1": [8, 9, 16, 19], "uuid": 8, "newli": 8, "metadata": [8, 9, 16, 18], "uid": 8, "12a3678d": 8, "8511": 8, "4c9c": 8, "8a48": 8, "fa78d3992694": 8, "somewher": 8, "might": [8, 13], "grant": 8, "lookup": 8, "patch": [8, 15, 19], "json": 8, "rule": 8, "apigroup": 8, "verb": 8, "amend": 8, "109m": 8, "96": 8, "66": 8, "22": [8, 17], "108m": 8, "246": 8, "106m": 8, "ownerrefer": 8, "column": 8, "lower": [8, 18], "110m": 8, "107m": 8, "st": [8, 19], "104m": 8, "bound": [8, 10, 13, 16], "old": [8, 13, 19], "boot": [8, 15], "600": 8, "initi": [8, 18], "initcontain": 8, "bump": 8, "introduc": [9, 16], "endpointsselector": 9, "matchlabel": 9, "ident": 9, "volumeclaimtempl": 9, "exposeopt": 9, "webinterfac": 9, "ingressclassnam": 9, "dnsdomain": 9, "annot": 9, "passthrough": 9, "explain": [9, 16, 18], "mai": [9, 10, 12, 13, 14, 15, 16, 17, 18, 19], "futur": 9, "third": 9, "parti": 9, "skip": 9, "side": [9, 19], "5m": 9, "met": 9, "degrad": 9, "revis": 9, "65b89d55bb": 9, "outsid": 9, "recommend": [9, 19], "matter": 9, "packet": [9, 16], "tl": 9, "sni": 9, "caller": 9, "rout": 9, "properli": [9, 15, 19], "real": 9, "address": [9, 13, 14], "grafana_serving_cert": 9, "index": 9, "base64": 9, "d": [9, 14, 18, 19], "grafana_us": 9, "admin": 9, "usernam": [9, 14], "grafana_password": 9, "appropri": 9, "record": 9, "often": [9, 18], "wildcard": 9, "mydomain": 9, "usual": [9, 17, 18], "cname": 9, "adjust": [9, 18], "similar": 9, "curl": 9, "dev": [9, 18], "null": 9, "w": 9, "http_code": 9, "cacert": 9, "echo": 9, "200": 9, "beyond": 9, "unless": 9, "assum": 9, "ingress_port": 9, "loadbalanc": 9, "reachabl": 9, "ingress_ip": 9, "slightli": [9, 18], "conveni": 9, "internal_ip": 9, "external_ip": 9, "rang": [9, 18], "item": 9, "eq": 9, "internalip": 9, "incid": 10, "explicit": 10, "becom": [10, 15, 17], "pvc": 10, "affin": 10, "automaticorphanednodecleanup": [10, 18], "flag": [10, 19], "hi": 10, "cleanup": [11, 15, 18], "lost": 11, "mainten": [11, 15], "restor": [11, 15, 19], "probe": [12, 19], "return": 12, "failur": [12, 13, 15, 18], "live": 12, "succe": 12, "load": [12, 13, 14, 18], "balanc": 12, "registri": 12, "stai": 12, "aliv": 12, "turn": [12, 15, 19], "bring": [12, 13, 15, 19], "front": 12, "east1": 12, "possibl": [13, 18], "stream": 13, "bandwidth": 13, "nodetool": 13, "c": [13, 14], "normal": 13, "leav": [13, 16], "join": 13, "move": [13, 15, 16], "token": [13, 18], "un": 13, "125": 13, "110": 13, "74": 13, "63": 13, "kb": 13, "256": 13, "8ebd6114": 13, "969c": 13, "44af": 13, "a978": 13, "87a4a6c65c3": 13, "189": 13, "91": 13, "03": [13, 17], "35d0cb19": 13, "35ef": 13, "482b": 13, "92a4": 13, "b63eee4527e5": 13, "77": 13, "1ffa7a82": 13, "c41c": 13, "4706": 13, "8f5f": 13, "4d45a39c7003": 13, "identifi": [13, 14], "3h12m": 13, "3h11m": 13, "3h5m": 13, "drain": [13, 15], "given": [13, 18], "b4b390a1": 13, "6j12": 13, "ignor": 13, "daemonset": [13, 16], "pend": 13, "3h21m": 13, "3h19m": 13, "8m14": 13, "recreat": [13, 14, 19], "3h27m": 13, "3h25m": 13, "9": [13, 14, 15, 17, 19], "store": [13, 14, 18], "visibl": 13, "191": 13, "172": 13, "sync": 13, "fresh": [14, 19], "snapshot": [14, 15, 18], "cluster_id": 14, "backup_loc": 14, "sm_20201227144037utc": 14, "409mib": 14, "sm_20201228145917utc": 14, "434mib": 14, "tabl": [14, 17, 18], "system_schema": [14, 15], "snapshot_tag": 14, "schema": [14, 15], "archiv": 14, "ed63b474": 14, "2c05": 14, "4f4f": 14, "b084": 14, "94541dd86e7a": 14, "task_287791d9": 14, "c257": 14, "4850": 14, "aef5": 14, "7537d6e69d90_tag_sm_20201228145917utc_schema": 14, "tar": 14, "gz": 14, "cp": 14, "ztvf": 14, "rw": 14, "12671": 14, "17": [14, 17], "2216": 14, "921": 14, "12567": 14, "4113": 14, "proce": 14, "backup_fil": 14, "sstableload": 14, "structur": 14, "temporari": 14, "cat": [14, 19], "awk": 14, "xarg": [14, 19], "n2": 14, "togeth": 14, "data_0": 14, "big": 14, "detect": 15, "semant": 15, "non": 15, "nightli": 15, "so_data_20201228135002utc": 15, "validate_upgrad": 15, "so_system_20201228135002utc": 15, "parallel": [15, 18], "underli": [15, 18], "ondelet": 15, "upgradestrategi": 15, "everi": [15, 17], "trace": 15, "displai": 15, "begin_upgrad": 15, "check_schema_agr": 15, "minut": 15, "create_system_backup": 15, "find_next_rack": 15, "decis": 15, "upgrade_image_in_pod_spec": 15, "find_next_nod": 15, "enable_maintenance_mod": 15, "drain_nod": 15, "backup_data": 15, "disable_maintenance_mod": 15, "delete_pod": 15, "clear_data_backup": 15, "clear_system_backup": 15, "restore_upgrade_strategi": 15, "finish_upgrad": 15, "recov": 15, "stuck": 15, "refus": 15, "replica": [15, 18], "zero": 15, "root": 15, "sstabl": 15, "left": [15, 18], "nodeconfig": 16, "suppos": 16, "cover": 16, "placement": [16, 18], "perftun": 16, "optmiz": 16, "kernel": 16, "devic": 16, "spread": 16, "irq": 16, "across": [16, 18], "assign": 16, "immedi": 16, "effic": 16, "pin": [16, 18, 19], "interrupt": 16, "One": 16, "context": 16, "switch": 16, "share": [16, 18], "coupl": 16, "daemon": 16, "entir": 16, "space": 16, "advantag": 16, "exclus": 16, "special": 16, "qo": 16, "doubl": 16, "meet": 16, "cf": 16, "quota": 16, "enforc": 16, "workload": 16, "around": 16, "howev": 16, "distribut": 16, "within": 16, "part": [16, 18], "fulfil": 16, "receiv": 16, "equal": [16, 18], "agentresourc": [16, 18], "500gi": 16, "1g": 16, "16g": 16, "aim": 17, "ship": 17, "approxim": 17, "week": 17, "advisori": 17, "hit": 17, "code": [17, 19], "freez": 17, "2022": 17, "01": 17, "2021": 17, "08": 17, "everyon": 17, "2023": 17, "05": 17, "21": 17, "elig": 17, "situat": 17, "assess": 17, "action": 17, "branch": [17, 19], "trigger": 17, "build": 17, "publish": 17, "artifact": 17, "e2": 17, "suit": 17, "vx": 17, "y": 17, "x": 17, "alpha": 17, "rc": 17, "ga": 17, "aren": 17, "scratch": [17, 19], "rather": 17, "candid": 17, "qualiti": 17, "qa": 17, "sing": 17, "sha": 17, "Be": 17, "function": 17, "gt": 17, "amp": 17, "lt": 17, "19": 17, "11": 17, "cri": 17, "v1alpha2": 17, "page": [18, 19], "intens": 18, "ratelimit": 18, "500g": 18, "storageclassnam": 18, "raid": 18, "32gi": 18, "nodeaffin": 18, "requiredduringschedulingignoredduringexecut": 18, "nodeselectorterm": 18, "matchexpress": 18, "domain": 18, "effect": 18, "unset": 18, "agentrepositori": 18, "orphan": 18, "genericupgrad": 18, "failurestrategi": 18, "poll": 18, "sent": 18, "kube": 18, "apiserv": 18, "affect": 18, "overal": 18, "spent": 18, "scyllaarg": 18, "paramet": 18, "dnspolici": 18, "model": 18, "moment": 18, "schedul": 18, "human": 18, "readabl": 18, "uniqu": 18, "startdat": 18, "rfc3339": 18, "e": [18, 19], "3d2h10m": 18, "numretri": 18, "glob": 18, "dc1": 18, "otherdc": 18, "exclud": 18, "failfast": 18, "stop": 18, "shard": 18, "integ": 18, "higher": 18, "faster": 18, "impact": 18, "granular": 18, "resum": 18, "row": 18, "decim": 18, "percent": 18, "string": 18, "float": 18, "runtim": 18, "replic": 18, "factor": 18, "rf": 18, "formula": 18, "calcul": 18, "table_prefix_": 18, "smalltablethreshold": 18, "threshold": 18, "mib": 18, "tib": 18, "1gib": 18, "alphanumer": 18, "dot": 18, "charact": 18, "forbidden": 18, "gc": 18, "megabyt": 18, "snapshotparallel": 18, "global": 18, "uploadparallel": 18, "correspond": 18, "confus": 18, "storageclass": 18, "ram": 18, "minimum": 18, "amount": 18, "volumemount": 18, "agentvolumemount": 18, "scyllaconfig": 18, "scyllaagentconfig": 18, "subfield": 18, "podaffin": 18, "podantiaffin": 18, "There": 19, "5871": 19, "7735": 19, "release_nam": 19, "tmpdir": 19, "mktemp": 19, "untar": 19, "untardir": 19, "printf": 19, "minor": 19, "symlink": 19, "expect": 19, "brought": 19, "lot": 19, "ones": 19, "mutatingwebhookconfigur": 19, "mutat": 19, "validatingwebhookconfigur": 19, "plane": 19, "95m": 19, "livenessprob": 19, "httpget": 19, "healthz": 19, "8080": 19, "scheme": 19, "readinessprob": 19, "retainkei": 19, "readyz": 19, "preserv": 19}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"contribut": 0, "scylla": [0, 1, 2, 3, 4, 5, 6, 7, 11, 13, 15, 18, 19], "oper": [0, 1, 2, 3, 4, 5, 9, 11, 19], "prerequisit": [0, 2, 4, 7, 9], "initi": [0, 2], "setup": [0, 1, 3], "creat": [0, 1, 2, 3], "fork": 0, "clone": 0, "your": 0, "add": 0, "upstream": 0, "remot": 0, "develop": 0, "build": 0, "project": 0, "branch": 0, "updat": 0, "submit": 0, "pull": 0, "request": 0, "commit": 0, "histori": 0, "messag": 0, "deploi": [1, 2, 3, 4, 7, 9], "ek": 1, "tl": [1, 3, 4], "dr": [1, 3, 4], "walkthrough": [1, 3], "configur": [1, 2, 3], "environ": [1, 3], "variabl": [1, 3], "an": [1, 9], "cluster": [1, 2, 3, 7, 18], "instal": [1, 3, 4], "requir": [1, 3, 9], "tool": [1, 3], "script": 1, "third": 1, "parti": 1, "depend": 1, "local": [1, 2, 3], "provision": [1, 3], "tune": [1, 16], "daemonset": [1, 3], "access": [1, 2, 3, 9], "databas": [1, 2, 3], "delet": [1, 3], "kubernet": [2, 3, 7, 16], "run": 2, "download": 2, "cert": [2, 4], "manag": [2, 4, 6, 7, 9, 18], "host": 2, "network": 2, "contain": 2, "kernel": 2, "paramet": 2, "altern": 2, "agent": 2, "auth": 2, "token": 2, "set": [2, 3, 18], "up": [2, 6, 7], "monitor": [2, 4, 9], "scale": 2, "benchmark": 2, "cassandra": 2, "stress": 2, "down": 2, "clean": [2, 7], "troubleshoot": [2, 7], "gke": 3, "googl": 3, "engin": 3, "yourself": 3, "admin": 3, "helm": [3, 4, 19], "xf": 3, "formatt": 3, "stack": 4, "us": [4, 9, 11], "chart": 4, "repositori": 4, "imag": 4, "resourc": 4, "webhook": 4, "custom": 4, "control": 4, "result": 4, "cleanup": [4, 10], "document": 5, "known": 6, "issu": 6, "doe": 6, "boot": 6, "minikub": 6, "truncat": 6, "queri": 6, "work": 6, "architectur": 7, "registr": 7, "task": 7, "schedul": [7, 17], "version": [8, 15], "migrat": 8, "v0": [8, 19], "3": [8, 19], "0": [8, 19], "v1": [8, 19], "procedur": 8, "prometheu": 9, "wait": 9, "roll": 9, "out": 9, "haproxi": 9, "ingress": 9, "scylladbmonitor": 9, "grafana": 9, "connect": 9, "through": 9, "resolv": 9, "domain": 9, "unresolv": 9, "variant": 9, "externalip": 9, "nodeport": 9, "automat": 10, "replac": [10, 13], "case": 10, "when": 10, "k8": 10, "node": [10, 11, 13, 16], "i": 10, "lost": 10, "mainten": 12, "mode": 12, "dead": 13, "restor": 14, "from": 14, "backup": 14, "upgrad": [15, 19], "perform": 16, "releas": 17, "support": 17, "backport": 17, "polici": 17, "ci": 17, "cd": 17, "autom": 17, "promot": 17, "gener": 17, "avail": 17, "matrix": 17, "crd": 18, "sampl": 18, "explan": 18, "datacent": 18, "rack": 18, "via": 19, "kubectl": 19, "2": 19, "1": 19}, "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": {"Maintenance mode": [[12, "maintenance-mode"]], "Replacing a Scylla node": [[13, "replacing-a-scylla-node"]], "Replacing a dead node": [[13, "replacing-a-dead-node"]], "Restore from backup": [[14, "restore-from-backup"]], "Automatic cleanup and replacement in case when k8s node is lost": [[10, "automatic-cleanup-and-replacement-in-case-when-k8s-node-is-lost"]], "Node operations using Scylla Operator": [[11, "node-operations-using-scylla-operator"]], "Known issues": [[6, "known-issues"]], "Scylla Manager does not boot up on Minikube": [[6, "scylla-manager-does-not-boot-up-on-minikube"]], "TRUNCATE queries does not work on Minikube": [[6, "truncate-queries-does-not-work-on-minikube"]], "Version migrations": [[8, "version-migrations"]], "v0.3.0 -> v1.0.0 migration": [[8, "v0-3-0-v1-0-0-migration"]], "Procedure": [[8, "procedure"]], "Scylla Operator Documentation": [[5, "scylla-operator-documentation"]], "Deploying Scylla Manager on a Kubernetes Cluster": [[7, "deploying-scylla-manager-on-a-kubernetes-cluster"]], "Prerequisites": [[7, "prerequisites"], [9, "prerequisites"], [4, "prerequisites"], [2, "prerequisites"], [0, "prerequisites"]], "Architecture": [[7, "architecture"]], "Deploy Scylla Manager": [[7, "deploy-scylla-manager"]], "Cluster registration": [[7, "cluster-registration"]], "Task scheduling": [[7, "task-scheduling"]], "Clean Up": [[7, "clean-up"], [2, "clean-up"]], "Troubleshooting": [[7, "troubleshooting"], [2, "troubleshooting"]], "Monitoring": [[9, "monitoring"], [4, "monitoring"]], "Deploy managed monitoring": [[9, "deploy-managed-monitoring"]], "Requirements": [[9, "requirements"]], "Deploy Prometheus Operator": [[9, "deploy-prometheus-operator"]], "Wait for Prometheus Operator to roll out": [[9, "wait-for-prometheus-operator-to-roll-out"]], "Deploy HAProxy Ingress": [[9, "deploy-haproxy-ingress"]], "Wait for HAProxy Ingress to roll out": [[9, "wait-for-haproxy-ingress-to-roll-out"]], "Deploy ScyllaDBMonitoring": [[9, "deploy-scylladbmonitoring"]], "Wait for ScyllaDBMonitoring to roll out": [[9, "wait-for-scylladbmonitoring-to-roll-out"]], "Wait for Prometheus to roll out": [[9, "wait-for-prometheus-to-roll-out"]], "Wait for Grafana to roll out": [[9, "wait-for-grafana-to-roll-out"]], "Accessing Grafana": [[9, "accessing-grafana"]], "Connecting through Ingress using a resolvable domain": [[9, "connecting-through-ingress-using-a-resolvable-domain"]], "Connecting through Ingress using an unresolvable domain": [[9, "connecting-through-ingress-using-an-unresolvable-domain"]], "Variants": [[9, "variants"]], "Ingress ExternalIP": [[9, "ingress-externalip"]], "Ingress NodePort": [[9, "ingress-nodeport"]], "Connection": [[9, "connection"]], "Upgrading version of Scylla": [[15, "upgrading-version-of-scylla"]], "Upgrade of Scylla Operator": [[19, "upgrade-of-scylla-operator"]], "Upgrade via Helm": [[19, "upgrade-via-helm"]], "Upgrade via kubectl": [[19, "upgrade-via-kubectl"]], "v1.2.0 -> v1.3.0": [[19, "v1-2-0-v1-3-0"]], "v1.1.0 -> v1.2.0": [[19, "v1-1-0-v1-2-0"]], "v1.0.0 -> v1.1.0": [[19, "v1-0-0-v1-1-0"]], "v0.3.0 -> v1.0.0": [[19, "v0-3-0-v1-0-0"]], "Releases": [[17, "releases"]], "Schedule": [[17, "schedule"]], "Supported releases": [[17, "supported-releases"]], "Backport policy": [[17, "backport-policy"]], "CI/CD": [[17, "ci-cd"]], "Automated promotions": [[17, "automated-promotions"]], "Generally available": [[17, "generally-available"]], "Support matrix": [[17, "support-matrix"]], "Performance tuning": [[16, "performance-tuning"]], "Node tuning": [[16, "node-tuning"]], "Kubernetes tuning": [[16, "kubernetes-tuning"]], "Scylla Cluster CRD": [[18, "scylla-cluster-crd"]], "Sample": [[18, "sample"]], "Settings Explanation": [[18, "settings-explanation"]], "Cluster Settings": [[18, "cluster-settings"]], "Scylla Manager settings": [[18, "scylla-manager-settings"]], "Datacenter Settings": [[18, "datacenter-settings"]], "Rack Settings": [[18, "rack-settings"]], "Deploying Scylla stack using Helm Charts": [[4, "deploying-scylla-stack-using-helm-charts"]], "TL;DR": [[4, "tl-dr"]], "Deploy Cert Manager": [[4, "deploy-cert-manager"], [2, "deploy-cert-manager"]], "Helm Chart repository": [[4, "helm-chart-repository"]], "Scylla Operator Chart": [[4, "scylla-operator-chart"]], "image": [[4, "image"]], "resources": [[4, "resources"]], "webhook": [[4, "webhook"]], "Customization": [[4, "customization"], [4, "id1"], [4, "id3"]], "Installation": [[4, "installation"], [4, "id2"], [4, "id4"]], "Scylla Helm Chart": [[4, "scylla-helm-chart"]], "Scylla Manager Helm Chart": [[4, "scylla-manager-helm-chart"]], "Scylla Manager": [[4, "scylla-manager"]], "Scylla Manager Controller": [[4, "scylla-manager-controller"]], "Scylla": [[4, "scylla"]], "Results": [[4, "results"]], "Cleanup": [[4, "cleanup"]], "Deploying Scylla on GKE": [[3, "deploying-scylla-on-gke"]], "TL;DR;": [[3, "tl-dr"], [1, "tl-dr"]], "Walkthrough": [[3, "walkthrough"], [1, "walkthrough"]], "Google Kubernetes Engine Setup": [[3, "google-kubernetes-engine-setup"]], "Configure environment variables": [[3, "configure-environment-variables"], [1, "configure-environment-variables"]], "Creating a GKE cluster": [[3, "creating-a-gke-cluster"]], "Setting Yourself as cluster-admin": [[3, "setting-yourself-as-cluster-admin"]], "Installing Required Tools": [[3, "installing-required-tools"], [1, "installing-required-tools"]], "Installing Helm": [[3, "installing-helm"]], "Install xfs-formatter DaemonSet": [[3, "install-xfs-formatter-daemonset"]], "Install the local provisioner": [[3, "install-the-local-provisioner"], [1, "install-the-local-provisioner"]], "Deploy Scylla cluster": [[3, "deploy-scylla-cluster"]], "Installing the Scylla Operator and Scylla": [[3, "installing-the-scylla-operator-and-scylla"], [1, "installing-the-scylla-operator-and-scylla"]], "Accessing the database": [[3, "accessing-the-database"], [1, "accessing-the-database"]], "Deleting a GKE cluster": [[3, "deleting-a-gke-cluster"]], "Deploying Scylla on EKS": [[1, "deploying-scylla-on-eks"]], "EKS Setup": [[1, "eks-setup"]], "Creating an EKS cluster": [[1, "creating-an-eks-cluster"]], "Installing script third party dependencies": [[1, "installing-script-third-party-dependencies"]], "Deploy tuning DaemonSet": [[1, "deploy-tuning-daemonset"]], "Deleting an EKS cluster": [[1, "deleting-an-eks-cluster"]], "Deploying Scylla on a Kubernetes Cluster": [[2, "deploying-scylla-on-a-kubernetes-cluster"]], "Running locally": [[2, "running-locally"]], "Download Scylla Operator": [[2, "download-scylla-operator"]], "Deploy Scylla Operator": [[2, "deploy-scylla-operator"]], "Create and Initialize a Scylla Cluster": [[2, "create-and-initialize-a-scylla-cluster"]], "Configure host networking": [[2, "configure-host-networking"]], "Configure container kernel parameters": [[2, "configure-container-kernel-parameters"]], "Deploying Alternator": [[2, "deploying-alternator"]], "Accessing the Database": [[2, "accessing-the-database"]], "Configure Scylla": [[2, "configure-scylla"]], "Configure Scylla Manager Agent": [[2, "configure-scylla-manager-agent"]], "Scylla Manager Agent auth token": [[2, "scylla-manager-agent-auth-token"]], "Set up monitoring": [[2, "set-up-monitoring"]], "Scale Up": [[2, "scale-up"]], "Benchmark with cassandra-stress": [[2, "benchmark-with-cassandra-stress"]], "Scale Down": [[2, "scale-down"]], "Contributing to Scylla Operator": [[0, "contributing-to-scylla-operator"]], "Initial Setup": [[0, "initial-setup"]], "Create a Fork": [[0, "create-a-fork"]], "Clone Your Fork": [[0, "clone-your-fork"]], "Add Upstream Remote": [[0, "add-upstream-remote"]], "Development": [[0, "development"]], "Building the project": [[0, "building-the-project"]], "Create a Branch": [[0, "create-a-branch"]], "Updating Your Fork": [[0, "updating-your-fork"]], "Submitting a Pull Request": [[0, "submitting-a-pull-request"]], "Commit History": [[0, "commit-history"]], "Commit messages": [[0, "commit-messages"]], "Submitting": [[0, "submitting"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/v1.9/sitemap.xml b/v1.9/sitemap.xml new file mode 100644 index 00000000000..e4721c5772f --- /dev/null +++ b/v1.9/sitemap.xml @@ -0,0 +1,2 @@ + +https://operator.docs.scylladb.com/stable/contributing.htmlhttps://operator.docs.scylladb.com/stable/eks.htmlhttps://operator.docs.scylladb.com/stable/generic.htmlhttps://operator.docs.scylladb.com/stable/gke.htmlhttps://operator.docs.scylladb.com/stable/manager.htmlhttps://operator.docs.scylladb.com/stable/helm.htmlhttps://operator.docs.scylladb.com/stable/index.htmlhttps://operator.docs.scylladb.com/stable/migration.htmlhttps://operator.docs.scylladb.com/stable/known_issues.htmlhttps://operator.docs.scylladb.com/stable/monitoring.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/automatic_cleanup.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/replace_node.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/index.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/maintenance_mode.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/restore.htmlhttps://operator.docs.scylladb.com/stable/upgrade.htmlhttps://operator.docs.scylladb.com/stable/nodeoperations/scylla_upgrade.htmlhttps://operator.docs.scylladb.com/stable/performance.htmlhttps://operator.docs.scylladb.com/stable/releases.htmlhttps://operator.docs.scylladb.com/stable/scylla_cluster_crd.htmlhttps://operator.docs.scylladb.com/stable/genindex.htmlhttps://operator.docs.scylladb.com/stable/404.htmlhttps://operator.docs.scylladb.com/stable/search.html \ No newline at end of file diff --git a/v1.9/upgrade.html b/v1.9/upgrade.html new file mode 100644 index 00000000000..00d7bb6c3e8 --- /dev/null +++ b/v1.9/upgrade.html @@ -0,0 +1,781 @@ + + + + + + + + + + + + + Upgrade of Scylla Operator | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              + + + +
              +
              + Menu +
              +
              +
              +
              +
              + + +
              +

              Caution

              +

              + + You're viewing documentation for a previous version of Scylla Operator. + + Switch to the latest stable version. +

              +
              + + + +
              + +
              + +
              +

              Upgrade of Scylla Operator

              +

              This page describes Scylla Operator upgrade procedures.
              There are two generic update procedures - via Helm and via kubectl. Before upgrading, please check this page to find out +if your target version requires additional upgrade steps.

              +
              +

              Upgrade via Helm

              +

              Helm doesn’t support managing CustomResourceDefinition resources (#5871, #7735)
              These are only created on first install and never updated. In order to update them, users have to do it manually.

              +

              Replace <release_name> with the name of your Helm release for Scylla Operator and replace <version> with the version number you want to install:

              +
                +
              1. Make sure Helm chart repository is up-to-date:

                +
                helm repo add scylla-operator https://storage.googleapis.com/scylla-operator-charts/stable
                +helm repo update
                +
                +
                +
              2. +
              3. Update CRD resources. We recommend using --server-side flag for kubectl apply, if your version supports it.

                +
                tmpdir=$( mktemp -d ) \
                +  && helm pull scylla-operator/scylla-operator --version <version> --untar --untardir "${tmpdir}" \
                +  && find "${tmpdir}"/scylla-operator/crds/ -name '*.yaml' -printf '-f=%p ' \
                +  | xargs kubectl apply
                +
                +
                +
              4. +
              5. Update Scylla Operator

                +
                helm upgrade --version <version> <release_name> scylla-operator/scylla-operator
                +
                +
                +
              6. +
              +
              +
              +

              Upgrade via kubectl

              +

              Replace <version> with the version number you want to install:

              +
                +
              1. Checkout source code of version you want to use:

                +
                git checkout <version>
                +
                +
                +
              2. +
              3. Manifests use rolling minor version tag, you may want to pin it to specific version:

                +
                find deploy/operator -name "*.yaml" | xargs sed --follow-symlinks -i -E "s^docker.io/scylladb/scylla-operator:[0-9]+\.[0-9]+^docker.io/scylladb/scylla-operator:<version>^g"
                +
                +
                +
              4. +
              5. Update Scylla Operator. We recommend using --server-side flag for kubectl apply, if your version supports it.

                +
                kubectl apply -f deploy/operator
                +
                +
                +
              6. +
              +
              +
              +
              +

              v1.2.0 -> v1.3.0

              +

              Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

              +
                +
              1. Checkout source code of v1.3.0:

                +
                git checkout v1.3.0
                +
                +
                +
              2. +
              3. Update Scylla Operator from deploy directory:

                +
                kubectl -n scylla-operator apply -f deploy/operator
                +
                +
                +
              4. +
              5. Wait until Scylla Operator is up and running:

                +
                kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
                +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
                +
                +
                +
              6. +
              +
              +
              +

              v1.1.0 -> v1.2.0

              +

              1.2.0 release brought a lot of changes to the Scylla Operator deployment process. +To properly update Scylla Operator one must delete old objects and install updated ones.

              +

              Sidecar image is going to be upgraded automatically, so a rolling restart of your Scylla clusters is expected during the upgrade procedure.

              +
                +
              1. Checkout source code of v1.2.0:

                +
                git checkout v1.2.0
                +
                +
                +
              2. +
              3. Remove old scylla operator namespace - in our case it’s called scylla-operator-system:

                +
                kubectl delete namespace scylla-operator-system --wait=true
                +
                +
                +
              4. +
              5. Remove old webhooks:

                +
                kubectl delete MutatingWebhookConfiguration scylla-operator-mutating-webhook-configuration
                +kubectl delete ValidatingWebhookConfiguration scylla-operator-validating-webhook-configuration
                +
                +
                +
              6. +
              7. Install Scylla Operator from deploy directory:

                +
                kubectl -n scylla-operator apply -f deploy/operator
                +
                +
                +
              8. +
              9. Wait until Scylla Operator is up and running:

                +
                kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com
                +kubectl -n scylla-operator rollout status deployment.apps/scylla-operator
                +
                +
                +
              10. +
              +
              +
              +

              v1.0.0 -> v1.1.0

              +

              During this update we will change probes and image for Scylla Operator. +A new version brings an automation for upgrade of sidecar image, so a rolling restart of managed Scylla clusters is expected.

              +
                +
              1. Get name of StatefulSet managing Scylla Operator

                +
                kubectl --namespace scylla-operator-system get sts --selector="control-plane=controller-manager"
                +
                +NAME                                 READY   AGE
                +scylla-operator-controller-manager   1/1     95m
                +
                +
                +
              2. +
              3. Change probes and used container image by applying following patch:

                +
                spec:
                +  template:
                +    spec:
                +      containers:
                +      - name: manager
                +        image: docker.io/scylladb/scylla-operator:1.1.0
                +        livenessProbe:
                +          httpGet:
                +            path: /healthz
                +            port: 8080
                +            scheme: HTTP
                +        readinessProbe:
                +          $retainKeys:
                +          - httpGet
                +          httpGet:
                +            path: /readyz
                +            port: 8080
                +            scheme: HTTP
                +
                +
                +

                To apply above patch save it to file (operator-patch.yaml for example) and apply to Operator StatefulSet:

                +
                kubectl -n scylla-operator-system patch sts scylla-operator-controller-manager --patch "$(cat operator-patch.yaml)"
                +
                +
                +
              4. +
              +
              +
              +

              v0.3.0 -> v1.0.0

              +

              Note: There’s an experimental migration procedure available here.

              +

              v0.3.0 used a very common name as a CRD kind (Cluster). In v1.0.0 this issue was solved by using less common +kind which is easier to disambiguate. (ScyllaCluster). +This change is backward incompatible, so Scylla cluster must be turned off and recreated from scratch. +In case you need to preserve your data, refer to backup and restore guide.

              +
                +
              1. Get list of existing Scylla clusters

                +
                kubectl -n scylla get cluster.scylla.scylladb.com
                +
                +NAME             AGE
                +simple-cluster   30m
                +
                +
                +
              2. +
              3. Delete each one of them

                +
                kubectl -n scylla delete cluster.scylla.scylladb.com simple-cluster
                +
                +
                +
              4. +
              5. Make sure you’re on v0.3.0 branch

                +
                git checkout v0.3.0
                +
                +
                +
              6. +
              7. Delete existing CRD and Operator

                +
                kubectl delete -f examples/generic/operator.yaml
                +
                +
                +
              8. +
              9. Checkout v1.0.0 version

                +
                git checkout v1.0.0
                +
                +
                +
              10. +
              11. Install new CRD and Scylla Operator

                +
                kubectl apply -f examples/common/operator.yaml
                +
                +
                +
              12. +
              13. Migrate your existing Scylla Cluster definition. Change apiVersion and kind from:

                +
                apiVersion: scylla.scylladb.com/v1alpha1
                +kind: Cluster
                +
                +
                +

                to:

                +
                apiVersion: scylla.scylladb.com/v1
                +kind: ScyllaCluster
                +
                +
                +
              14. +
              15. Once your cluster definition is ready, use kubectl apply to install fresh Scylla cluster.

              16. +
              +
              +
              + + +
              + + + + + + + +
              + +
              + + + + +
              + + + + + + + \ No newline at end of file