diff --git a/main/404.html b/main/404.html index a4225d5ff..61a3a7ff4 100644 --- a/main/404.html +++ b/main/404.html @@ -1 +1 @@ - Chainsaw

404 - Not found

\ No newline at end of file + Chainsaw

404 - Not found

\ No newline at end of file diff --git a/main/assets/stylesheets/main.0253249f.min.css b/main/assets/stylesheets/main.0253249f.min.css deleted file mode 100644 index 9a7a6982d..000000000 --- a/main/assets/stylesheets/main.0253249f.min.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-scheme=default]{color-scheme:light}[data-md-color-scheme=default] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=default] img[src$="#only-dark"]{display:none}:root,[data-md-color-scheme=default]{--md-hue:225deg;--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008a;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#00000012;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-hl-color:#4287ff;--md-code-hl-color--light:#4287ff1a;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-mark-color:#ffff0080;--md-typeset-table-color:#0000001f;--md-typeset-table-color--light:rgba(0,0,0,.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-warning-fg-color:#000000de;--md-warning-bg-color:#ff9;--md-footer-fg-color:#fff;--md-footer-fg-color--light:#ffffffb3;--md-footer-fg-color--lighter:#ffffff73;--md-footer-bg-color:#000000de;--md-footer-bg-color--dark:#00000052;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent)}.md-typeset a code{color:currentcolor;transition:background-color 125ms}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}.md-typeset ul[type]{list-style-type:revert-layer}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}.md-typeset ol ol ol ol,.md-typeset ul ol ol ol{list-style-type:upper-alpha}.md-typeset ol ol ol ol ol,.md-typeset ul ol ol ol ol{list-style-type:upper-roman}.md-typeset ol[type],.md-typeset ul[type]{list-style-type:revert-layer}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}[dir=ltr] .md-typeset ol li ol,[dir=ltr] .md-typeset ol li ul,[dir=ltr] .md-typeset ul li ol,[dir=ltr] .md-typeset ul li ul{margin-left:.625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block;margin:0 auto}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td>:first-child,.md-typeset table:not([class]) th>:first-child{margin-top:0}.md-typeset table:not([class]) td>:last-child,.md-typeset table:not([class]) th>:last-child{margin-bottom:0}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:var(--md-typeset-table-color--light);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.984375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-typeset .md-author{border-radius:100%;display:block;flex-shrink:0;height:1.6rem;overflow:hidden;position:relative;transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .md-author img{display:block}.md-typeset .md-author--more{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .md-author--long{height:2.4rem;width:2.4rem}.md-typeset a.md-author{transform:scale(1)}.md-typeset a.md-author img{border-radius:100%;filter:grayscale(100%) opacity(75%);transition:filter 125ms}.md-typeset a.md-author:focus,.md-typeset a.md-author:hover{transform:scale(1.1);z-index:1}.md-typeset a.md-author:focus img,.md-typeset a.md-author:hover img{filter:grayscale(0)}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background-color:var(--md-warning-bg-color);color:var(--md-warning-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.no-js .md-banner__button{display:none}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.984375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;position:absolute;right:.5em;top:.5em;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:focus,.md-clipboard:hover{color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:focus code,.md-clipboard--inline:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .md-code__content{display:grid}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:#0000008a;height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.984375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{display:flex;flex-wrap:wrap;place-content:baseline center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}@media print{.md-feedback{display:none}}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{align-items:end;display:flex;flex-grow:0.01;margin-bottom:.4rem;margin-top:1rem;max-width:100%;outline-color:var(--md-accent-fg-color);overflow:hidden;transition:opacity .25s}.md-footer__link:focus,.md-footer__link:hover{opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.984375em){.md-footer__link--prev{flex-shrink:0}.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;margin-bottom:.7rem;max-width:calc(100% - 2.4rem);padding:0 1rem;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;opacity:.7}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:focus,html .md-footer-meta.md-typeset a:hover{color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{display:inline-flex;gap:.2rem;margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:focus,.md-typeset .md-button:hover{background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:focus,.md-typeset .md-input:hover{border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem #0000,0 .2rem .4rem #0000;color:var(--md-primary-bg-color);display:block;left:0;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.234375em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo img,.md-header__button.md-logo svg{fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-left:1rem;margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem;margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__option>input{bottom:0}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}.md-meta{color:var(--md-default-fg-color--light);font-size:.7rem;line-height:1.3}.md-meta__list{display:inline-flex;flex-wrap:wrap;list-style:none;margin:0;padding:0}.md-meta__item:not(:last-child):after{content:"·";margin-left:.2rem;margin-right:.2rem}.md-meta__link{color:var(--md-typeset-a-color)}.md-meta__link:focus,.md-meta__link:hover{color:var(--md-accent-fg-color)}.md-draft{background-color:#ff1744;border-radius:.125em;color:#fff;display:inline-block;font-weight:700;padding-left:.5714285714em;padding-right:.5714285714em}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{color:var(--md-default-fg-color--light);display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo img,.md-nav__title .md-nav__button.md-logo svg{fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__link{align-items:flex-start;display:flex;gap:.4rem;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active,.md-nav__item .md-nav__link--active code{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{position:relative}[dir=ltr] .md-nav__link .md-icon:last-child{margin-left:auto}[dir=rtl] .md-nav__link .md-icon:last-child{margin-right:auto}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em;position:relative}.md-nav__link[for]:focus,.md-nav__link[for]:hover,.md-nav__link[href]:focus,.md-nav__link[href]:hover{color:var(--md-accent-fg-color);cursor:pointer}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1;min-width:0}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.234375em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary .md-nav__item,.md-nav--primary .md-nav__title{font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest)}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:focus,.md-nav--primary .md-nav__item--active>.md-nav__link:hover{color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link svg{margin-top:.1em}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.984375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav{margin-bottom:-.4rem}.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--secondary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--secondary .md-nav__list{padding-right:.6rem}.md-nav--secondary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--secondary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--secondary .md-nav__item>.md-nav__link{margin-left:.4rem}}@media screen and (min-width:76.25em){.md-nav{margin-bottom:-.4rem;transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--primary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--primary .md-nav__list{padding-right:.6rem}.md-nav--primary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--primary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--primary .md-nav__item>.md-nav__link{margin-left:.4rem}.md-nav__toggle~.md-nav{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .25s,visibility 0ms .25s;visibility:collapse}.md-nav__toggle~.md-nav>.md-nav__list{overflow:hidden}.md-nav__toggle.md-toggle--indeterminate~.md-nav,.md-nav__toggle:checked~.md-nav{grid-template-rows:1fr;opacity:1;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .15s .1s,visibility 0ms;visibility:visible}.md-nav__toggle.md-toggle--indeterminate~.md-nav{transition:none}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link[for]{color:var(--md-default-fg-color--light)}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-icon,.md-nav__item--section>.md-nav__link>[for]{display:none}[dir=ltr] .md-nav__item--section>.md-nav{margin-left:-.6rem}[dir=rtl] .md-nav__item--section>.md-nav{margin-right:-.6rem}.md-nav__item--section>.md-nav{display:block;opacity:1;visibility:visible}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s;width:.9rem}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;border-radius:100%;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;vertical-align:-.1rem;width:100%}[dir=rtl] .md-nav__icon:after{transform:rotate(180deg)}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon:after,.md-nav__item--nested .md-toggle--indeterminate~.md-nav__link .md-nav__icon:after{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);margin-top:0;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active.md-nav__item--section{margin:0}[dir=ltr] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-left:-.6rem}[dir=rtl] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-right:-.6rem}.md-nav--lifted>.md-nav__list>.md-nav__item>[for]{color:var(--md-default-fg-color--light)}.md-nav--lifted .md-nav[data-md-level="1"]{grid-template-rows:1fr;opacity:1;visibility:visible}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__list{overflow:visible;padding-bottom:0}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}.md-pagination{font-size:.8rem;font-weight:700;gap:.4rem}.md-pagination,.md-pagination>*{align-items:center;display:flex;justify-content:center}.md-pagination>*{border-radius:.2rem;height:1.8rem;min-width:1.8rem;text-align:center}.md-pagination__current{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light)}.md-pagination__link{transition:color 125ms,background-color 125ms}.md-pagination__link:focus,.md-pagination__link:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-pagination__link:focus svg,.md-pagination__link:hover svg{color:var(--md-accent-fg-color)}.md-pagination__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-pagination__link svg{fill:currentcolor;color:var(--md-default-fg-color--lighter);display:block;max-height:100%;width:1.2rem}.md-post__back{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin-bottom:1.2rem;padding-bottom:1.2rem}@media screen and (max-width:76.234375em){.md-post__back{display:none}}[dir=rtl] .md-post__back svg{transform:scaleX(-1)}.md-post__authors{display:flex;flex-direction:column;gap:.6rem;margin:0 .6rem 1.2rem}.md-post .md-post__meta a{transition:color 125ms}.md-post .md-post__meta a:focus,.md-post .md-post__meta a:hover{color:var(--md-accent-fg-color)}.md-post__title{color:var(--md-default-fg-color--light);font-weight:700}.md-post--excerpt{margin-bottom:3.2rem}.md-post--excerpt .md-post__header{align-items:center;display:flex;gap:.6rem;min-height:1.6rem}.md-post--excerpt .md-post__authors{align-items:center;display:inline-flex;flex-direction:row;gap:.2rem;margin:0;min-height:2.4rem}[dir=ltr] .md-post--excerpt .md-post__meta .md-meta__list{margin-right:.4rem}[dir=rtl] .md-post--excerpt .md-post__meta .md-meta__list{margin-left:.4rem}.md-post--excerpt .md-post__content>:first-child{--md-scroll-margin:6rem;margin-top:0}.md-post>.md-nav--secondary{margin:1em 0}.md-profile{align-items:center;display:flex;font-size:.7rem;gap:.6rem;line-height:1.4;width:100%}.md-profile__description{flex-grow:1}.md-content--post{display:flex}@media screen and (max-width:76.234375em){.md-content--post{flex-flow:column-reverse}}.md-content--post>.md-content__inner{min-width:0}@media screen and (min-width:76.25em){[dir=ltr] .md-content--post>.md-content__inner{margin-left:1.2rem}[dir=rtl] .md-content--post>.md-content__inner{margin-right:1.2rem}}@media screen and (max-width:76.234375em){.md-sidebar.md-sidebar--post{padding:0;position:static;width:100%}.md-sidebar.md-sidebar--post .md-sidebar__scrollwrap{overflow:visible}.md-sidebar.md-sidebar--post .md-sidebar__inner{padding:0}.md-sidebar.md-sidebar--post .md-post__meta{margin-left:.6rem;margin-right:.6rem}.md-sidebar.md-sidebar--post .md-nav__item{border:none;display:inline}.md-sidebar.md-sidebar--post .md-nav__list{display:inline-flex;flex-wrap:wrap;gap:.6rem;padding-bottom:.6rem;padding-top:.6rem}.md-sidebar.md-sidebar--post .md-nav__link{padding:0}.md-sidebar.md-sidebar--post .md-nav{height:auto;margin-bottom:0;position:static}}:root{--md-progress-value:0;--md-progress-delay:400ms}.md-progress{background:var(--md-primary-bg-color);height:.075rem;opacity:min(clamp(0,var(--md-progress-value),1),clamp(0,100 - var(--md-progress-value),1));position:fixed;top:0;transform:scaleX(calc(var(--md-progress-value)*1%));transform-origin:left;transition:transform .5s cubic-bezier(.19,1,.22,1),opacity .25s var(--md-progress-delay);width:100%;z-index:4}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:#0000008a;cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__inner{float:right}[dir=rtl] .md-search__inner{float:left}.md-search__inner{padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}}@media screen and (min-width:60em) and (max-width:76.234375em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem #0000;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:#00000042;border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:#ffffff1f}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem #00000012;color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:#0000;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::placeholder{transition:color .25s}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.984375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:#0000}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>.md-icon{margin-left:.2rem}[dir=rtl] .md-search__options>.md-icon{margin-right:.2rem}.md-search__options>.md-icon{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>.md-icon:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.984375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:focus,.md-search-result__link:hover{background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more>summary{cursor:pointer;display:block;outline:none;position:sticky;scroll-snap-align:start;top:0;z-index:1}.md-search-result__more>summary::marker{display:none}.md-search-result__more>summary::-webkit-details-marker{display:none}.md-search-result__more>summary>div{color:var(--md-typeset-a-color);font-size:.64rem;padding:.75em .8rem;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more>summary>div{padding-left:2.2rem}[dir=rtl] .md-search-result__more>summary>div{padding-right:2.2rem}}.md-search-result__more>summary:focus>div,.md-search-result__more>summary:hover>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more[open]>summary{background-color:var(--md-default-bg-color)}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.984375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result .md-typeset{color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.6}.md-search-result .md-typeset h1{color:var(--md-default-fg-color);font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}.md-search-result .md-typeset h1 mark{text-decoration:none}.md-search-result .md-typeset h2{color:var(--md-default-fg-color);font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result .md-typeset h2 mark{text-decoration:none}.md-search-result__terms{color:var(--md-default-fg-color);display:block;font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color);text-decoration:underline}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:focus,.md-select__link:hover{color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.234375em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{scrollbar-gutter:stable;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap:focus-within,.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}}@media screen and (max-width:76.234375em){.md-overlay{background-color:#0000008a;height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-source-file{margin:1em 0}[dir=ltr] .md-source-file__fact{margin-right:.6rem}[dir=rtl] .md-source-file__fact{margin-left:.6rem}.md-source-file__fact{align-items:center;color:var(--md-default-fg-color--light);display:inline-flex;font-size:.68rem;gap:.3rem}.md-source-file__fact .md-icon{flex-shrink:0;margin-bottom:.05rem}[dir=ltr] .md-source-file__fact .md-author{float:left}[dir=rtl] .md-source-file__fact .md-author{float:right}.md-source-file__fact .md-author{margin-right:.2rem}.md-source-file__fact svg{width:.9rem}:root{--md-status:url('data:image/svg+xml;charset=utf-8,');--md-status--new:url('data:image/svg+xml;charset=utf-8,');--md-status--deprecated:url('data:image/svg+xml;charset=utf-8,');--md-status--encrypted:url('data:image/svg+xml;charset=utf-8,')}.md-status:after{background-color:var(--md-default-fg-color--light);content:"";display:inline-block;height:1.125em;-webkit-mask-image:var(--md-status);mask-image:var(--md-status);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.125em}.md-status:hover:after{background-color:currentcolor}.md-status--new:after{-webkit-mask-image:var(--md-status--new);mask-image:var(--md-status--new)}.md-status--deprecated:after{-webkit-mask-image:var(--md-status--deprecated);mask-image:var(--md-status--deprecated)}.md-status--encrypted:after{-webkit-mask-image:var(--md-status--encrypted);mask-image:var(--md-status--encrypted)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.234375em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;list-style:none;margin:0;overflow:auto;padding:0;scrollbar-width:none;white-space:nowrap}.md-tabs__list::-webkit-scrollbar{display:none}.md-tabs__item{height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__item--active .md-tabs__link{color:inherit;opacity:1}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link:focus,.md-tabs__link:hover{color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags:not([hidden]){display:inline-flex;flex-wrap:wrap;gap:.5em;margin-bottom:.75em;margin-top:-.125em}.md-typeset .md-tag{align-items:center;background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-flex;font-size:.64rem;font-size:min(.8em,.64rem);font-weight:700;gap:.5em;letter-spacing:normal;line-height:1.6;padding:.3125em .78125em}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon[href]:focus:before,.md-typeset .md-tag-icon[href]:hover:before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{transform:scale(.95)}75%{transform:scale(1)}to{transform:scale(.95)}}:root{--md-annotation-bg-icon:url('data:image/svg+xml;charset=utf-8,');--md-annotation-icon:url('data:image/svg+xml;charset=utf-8,')}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}.focus-visible>.md-tooltip,.md-tooltip:target{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-style:normal;font-weight:400;outline:none;text-align:initial;vertical-align:text-bottom;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}code .md-annotation{font-family:var(--md-code-font-family);font-size:inherit}.md-annotation:not([hidden]){display:inline-block;line-height:1.25}.md-annotation__index{border-radius:.01px;cursor:pointer;display:inline-block;margin-left:.4ch;margin-right:.4ch;outline:none;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none;vertical-align:text-top;z-index:0}.md-annotation .md-annotation__index{transition:z-index .25s}@media screen{.md-annotation__index{width:2.2ch}[data-md-visible]>.md-annotation__index{animation:pulse 2s infinite}.md-annotation__index:before{background:var(--md-default-bg-color);-webkit-mask-image:var(--md-annotation-bg-icon);mask-image:var(--md-annotation-bg-icon)}.md-annotation__index:after,.md-annotation__index:before{content:"";height:2.2ch;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:-.1ch;width:2.2ch;z-index:-1}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);-webkit-mask-image:var(--md-annotation-icon);mask-image:var(--md-annotation-icon);transform:scale(1.0001);transition:background-color .25s,transform .25s}.md-tooltip--active+.md-annotation__index:after{transform:rotate(45deg)}.md-tooltip--active+.md-annotation__index:after,:hover>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}}.md-tooltip--active+.md-annotation__index{animation-play-state:paused;transition-duration:0ms;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block}@media print{.md-annotation__index [data-md-annotation-id]{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);font-weight:700;padding:0 .6ch;white-space:nowrap}.md-annotation__index [data-md-annotation-id]:after{content:attr(data-md-annotation-id)}}.md-typeset .md-annotation-list{counter-reset:xxx;list-style:none}.md-typeset .md-annotation-list li{position:relative}[dir=ltr] .md-typeset .md-annotation-list li:before{left:-2.125em}[dir=rtl] .md-typeset .md-annotation-list li:before{right:-2.125em}.md-typeset .md-annotation-list li:before{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);content:counter(xxx);counter-increment:xxx;font-size:.8875em;font-weight:700;height:2ch;line-height:1.25;min-width:2ch;padding:0 .6ch;position:absolute;text-align:center;top:.25em}:root{--md-tooltip-width:20rem;--md-tooltip-tail:0.3rem}.md-tooltip2{-webkit-backface-visibility:hidden;backface-visibility:hidden;color:var(--md-default-fg-color);font-family:var(--md-text-font-family);opacity:0;pointer-events:none;position:absolute;top:calc(var(--md-tooltip-host-y) + var(--md-tooltip-y));transform:translateY(-.4rem);transform-origin:calc(var(--md-tooltip-host-x) + var(--md-tooltip-x)) 0;transition:transform 0ms .25s,opacity .25s,z-index .25s;width:100%;z-index:0}.md-tooltip2:before{border-left:var(--md-tooltip-tail) solid #0000;border-right:var(--md-tooltip-tail) solid #0000;content:"";display:block;left:clamp(1.5 * .8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-tail),100vw - 2 * var(--md-tooltip-tail) - 1.5 * .8rem);position:absolute;z-index:1}.md-tooltip2--top:before{border-top:var(--md-tooltip-tail) solid var(--md-default-bg-color);bottom:calc(var(--md-tooltip-tail)*-1 + .025rem);filter:drop-shadow(0 1px 0 hsla(0,0%,0%,.05))}.md-tooltip2--bottom:before{border-bottom:var(--md-tooltip-tail) solid var(--md-default-bg-color);filter:drop-shadow(0 -1px 0 hsla(0,0%,0%,.05));top:calc(var(--md-tooltip-tail)*-1 + .025rem)}.md-tooltip2--active{opacity:1;transform:translateY(0);transition:transform .4s cubic-bezier(0,1,.5,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip2__inner{scrollbar-gutter:stable;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);left:clamp(.8rem,var(--md-tooltip-host-x) - .8rem,100vw - var(--md-tooltip-width) - .8rem);max-height:40vh;max-width:calc(100vw - 1.6rem);position:relative;scrollbar-width:thin}.md-tooltip2__inner::-webkit-scrollbar{height:.2rem;width:.2rem}.md-tooltip2__inner::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-tooltip2__inner::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}[role=tooltip]>.md-tooltip2__inner{font-size:.5rem;font-weight:700;left:clamp(.8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-width)/2,100vw - var(--md-tooltip-width) - .8rem);max-width:min(100vw - 2 * .8rem,400px);padding:.2rem .4rem;-webkit-user-select:none;user-select:none;width:-moz-fit-content;width:fit-content}.md-tooltip2__inner.md-typeset>:first-child{margin-top:0}.md-tooltip2__inner.md-typeset>:last-child{margin-bottom:0}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:focus,.md-top:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__alias{margin-left:.3rem;opacity:.7}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:focus-within .md-version__list,.md-version:hover .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (hover:none),(pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:focus,.md-version__link:hover{color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:var(--md-admonition-bg-color);border:.075rem solid #448aff;border-radius:.2rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid;transition:box-shadow 125ms}@media print{.md-typeset .admonition,.md-typeset details{box-shadow:none}}.md-typeset .admonition:focus-within,.md-typeset details:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:2rem;padding-right:.6rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.6rem;padding-right:2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-left-width:.2rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-right-width:.2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset .admonition-title,.md-typeset summary{background-color:#448aff1a;border:none;font-weight:700;margin:0 -.6rem;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset .admonition-title:last-child,html .md-typeset summary:last-child{margin-bottom:0}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:.6rem}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:.6rem}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset .admonition-title code,.md-typeset summary code{box-shadow:0 0 0 .05rem var(--md-default-fg-color--lightest)}.md-typeset .admonition.note,.md-typeset details.note{border-color:#448aff}.md-typeset .admonition.note:focus-within,.md-typeset details.note:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .note>.admonition-title,.md-typeset .note>summary{background-color:#448aff1a}.md-typeset .note>.admonition-title:before,.md-typeset .note>summary:before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset .note>.admonition-title:after,.md-typeset .note>summary:after{color:#448aff}.md-typeset .admonition.abstract,.md-typeset details.abstract{border-color:#00b0ff}.md-typeset .admonition.abstract:focus-within,.md-typeset details.abstract:focus-within{box-shadow:0 0 0 .2rem #00b0ff1a}.md-typeset .abstract>.admonition-title,.md-typeset .abstract>summary{background-color:#00b0ff1a}.md-typeset .abstract>.admonition-title:before,.md-typeset .abstract>summary:before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset .abstract>.admonition-title:after,.md-typeset .abstract>summary:after{color:#00b0ff}.md-typeset .admonition.info,.md-typeset details.info{border-color:#00b8d4}.md-typeset .admonition.info:focus-within,.md-typeset details.info:focus-within{box-shadow:0 0 0 .2rem #00b8d41a}.md-typeset .info>.admonition-title,.md-typeset .info>summary{background-color:#00b8d41a}.md-typeset .info>.admonition-title:before,.md-typeset .info>summary:before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset .info>.admonition-title:after,.md-typeset .info>summary:after{color:#00b8d4}.md-typeset .admonition.tip,.md-typeset details.tip{border-color:#00bfa5}.md-typeset .admonition.tip:focus-within,.md-typeset details.tip:focus-within{box-shadow:0 0 0 .2rem #00bfa51a}.md-typeset .tip>.admonition-title,.md-typeset .tip>summary{background-color:#00bfa51a}.md-typeset .tip>.admonition-title:before,.md-typeset .tip>summary:before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset .tip>.admonition-title:after,.md-typeset .tip>summary:after{color:#00bfa5}.md-typeset .admonition.success,.md-typeset details.success{border-color:#00c853}.md-typeset .admonition.success:focus-within,.md-typeset details.success:focus-within{box-shadow:0 0 0 .2rem #00c8531a}.md-typeset .success>.admonition-title,.md-typeset .success>summary{background-color:#00c8531a}.md-typeset .success>.admonition-title:before,.md-typeset .success>summary:before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset .success>.admonition-title:after,.md-typeset .success>summary:after{color:#00c853}.md-typeset .admonition.question,.md-typeset details.question{border-color:#64dd17}.md-typeset .admonition.question:focus-within,.md-typeset details.question:focus-within{box-shadow:0 0 0 .2rem #64dd171a}.md-typeset .question>.admonition-title,.md-typeset .question>summary{background-color:#64dd171a}.md-typeset .question>.admonition-title:before,.md-typeset .question>summary:before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset .question>.admonition-title:after,.md-typeset .question>summary:after{color:#64dd17}.md-typeset .admonition.warning,.md-typeset details.warning{border-color:#ff9100}.md-typeset .admonition.warning:focus-within,.md-typeset details.warning:focus-within{box-shadow:0 0 0 .2rem #ff91001a}.md-typeset .warning>.admonition-title,.md-typeset .warning>summary{background-color:#ff91001a}.md-typeset .warning>.admonition-title:before,.md-typeset .warning>summary:before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset .warning>.admonition-title:after,.md-typeset .warning>summary:after{color:#ff9100}.md-typeset .admonition.failure,.md-typeset details.failure{border-color:#ff5252}.md-typeset .admonition.failure:focus-within,.md-typeset details.failure:focus-within{box-shadow:0 0 0 .2rem #ff52521a}.md-typeset .failure>.admonition-title,.md-typeset .failure>summary{background-color:#ff52521a}.md-typeset .failure>.admonition-title:before,.md-typeset .failure>summary:before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset .failure>.admonition-title:after,.md-typeset .failure>summary:after{color:#ff5252}.md-typeset .admonition.danger,.md-typeset details.danger{border-color:#ff1744}.md-typeset .admonition.danger:focus-within,.md-typeset details.danger:focus-within{box-shadow:0 0 0 .2rem #ff17441a}.md-typeset .danger>.admonition-title,.md-typeset .danger>summary{background-color:#ff17441a}.md-typeset .danger>.admonition-title:before,.md-typeset .danger>summary:before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset .danger>.admonition-title:after,.md-typeset .danger>summary:after{color:#ff1744}.md-typeset .admonition.bug,.md-typeset details.bug{border-color:#f50057}.md-typeset .admonition.bug:focus-within,.md-typeset details.bug:focus-within{box-shadow:0 0 0 .2rem #f500571a}.md-typeset .bug>.admonition-title,.md-typeset .bug>summary{background-color:#f500571a}.md-typeset .bug>.admonition-title:before,.md-typeset .bug>summary:before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset .bug>.admonition-title:after,.md-typeset .bug>summary:after{color:#f50057}.md-typeset .admonition.example,.md-typeset details.example{border-color:#7c4dff}.md-typeset .admonition.example:focus-within,.md-typeset details.example:focus-within{box-shadow:0 0 0 .2rem #7c4dff1a}.md-typeset .example>.admonition-title,.md-typeset .example>summary{background-color:#7c4dff1a}.md-typeset .example>.admonition-title:before,.md-typeset .example>summary:before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset .example>.admonition-title:after,.md-typeset .example>summary:after{color:#7c4dff}.md-typeset .admonition.quote,.md-typeset details.quote{border-color:#9e9e9e}.md-typeset .admonition.quote:focus-within,.md-typeset details.quote:focus-within{box-shadow:0 0 0 .2rem #9e9e9e1a}.md-typeset .quote>.admonition-title,.md-typeset .quote>summary{background-color:#9e9e9e1a}.md-typeset .quote>.admonition-title:before,.md-typeset .quote>summary:before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset .quote>.admonition-title:after,.md-typeset .quote>summary:after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:hover .footnote-backref,.md-typeset .footnote>ol>li:target .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :hover>.headerlink,.md-typeset :target>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset .headerlink:hover,.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset h1:target,.md-typeset h2:target,.md-typeset h3:target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.984375em){.md-typeset div.arithmatex{margin:0 -.8rem}.md-typeset div.arithmatex>*{width:min-content}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset div.arithmatex mjx-assistive-mml{height:0}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset del.critic,.md-typeset ins.critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem;overflow:hidden}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset .emojione,.md-typeset .gemoji,.md-typeset .twemoji{--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset .emojione svg,.md-typeset .gemoji svg,.md-typeset .twemoji svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset .lg,.md-typeset .xl,.md-typeset .xxl,.md-typeset .xxxl{vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight .o,.highlight .ow{color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight .cpf,.highlight .l,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .si,.highlight .ss{color:var(--md-code-hl-string-color)}.highlight .cp,.highlight .se,.highlight .sh,.highlight .sr,.highlight .sx{color:var(--md-code-hl-special-color)}.highlight .il,.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--md-code-hl-number-color)}.highlight .k,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:var(--md-code-hl-keyword-color)}.highlight .kc,.highlight .n{color:var(--md-code-hl-name-color)}.highlight .bp,.highlight .nb,.highlight .no{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight .ne,.highlight .nf,.highlight .nn{color:var(--md-code-hl-function-color)}.highlight .nd,.highlight .ni,.highlight .nl,.highlight .nt{color:var(--md-code-hl-keyword-color)}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm,.highlight .cs,.highlight .sd{color:var(--md-code-hl-comment-color)}.highlight .na,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--md-code-hl-variable-color)}.highlight .ge,.highlight .gh,.highlight .go,.highlight .gp,.highlight .gr,.highlight .gs,.highlight .gt,.highlight .gu{color:var(--md-code-hl-generic-color)}.highlight .gd,.highlight .gi{border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color--light);box-shadow:2px 0 0 0 var(--md-code-hl-color) inset;display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:sticky;-webkit-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying]{display:initial}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable tbody,.highlighttable td{display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;padding-right:.5882352941em}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.984375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:after,.md-typeset .keys kbd:before{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-set>input.focus-visible~.tabbed-labels:before{background-color:var(--md-accent-fg-color)}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-default-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,background-color .25s,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-default-fg-color)}.md-typeset .tabbed-labels>label>[href]:first-child{color:inherit}.md-typeset .tabbed-labels--linked>label{padding:0}.md-typeset .tabbed-labels--linked>label>a{display:block;padding:.78125em 1.25em .625em}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,#0000);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,#0000);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.984375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-default-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-default-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}@media print{.giscus,[id=__comments]{display:none}}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color);--md-mermaid-sequence-actor-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actor-fg-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-actor-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-actor-line-color:var(--md-default-fg-color--lighter);--md-mermaid-sequence-actorman-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actorman-line-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-box-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-box-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-label-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-label-fg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-loop-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-loop-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-loop-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-message-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-message-line-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-note-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-border-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-number-bg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-number-fg-color:var(--md-accent-bg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr));margin:1em 0}.md-typeset .grid.cards>ol,.md-typeset .grid.cards>ul{display:contents}.md-typeset .grid.cards>ol>li,.md-typeset .grid.cards>ul>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>ol>li:focus-within,.md-typeset .grid.cards>ol>li:hover,.md-typeset .grid.cards>ul>li:focus-within,.md-typeset .grid.cards>ul>li:hover,.md-typeset .grid>.card:focus-within,.md-typeset .grid>.card:hover{border-color:#0000;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>ol>li>hr,.md-typeset .grid.cards>ul>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>ol>li>:first-child,.md-typeset .grid.cards>ul>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>ol>li>:last-child,.md-typeset .grid.cards>ul>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*,.md-typeset .grid>.admonition,.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>.md-typeset details,.md-typeset .grid>details,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/main/assets/stylesheets/main.0253249f.min.css.map b/main/assets/stylesheets/main.0253249f.min.css.map deleted file mode 100644 index 748194709..000000000 --- a/main/assets/stylesheets/main.0253249f.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["src/templates/assets/stylesheets/main/components/_meta.scss","../../../../src/templates/assets/stylesheets/main.scss","src/templates/assets/stylesheets/main/_resets.scss","src/templates/assets/stylesheets/main/_colors.scss","src/templates/assets/stylesheets/main/_icons.scss","src/templates/assets/stylesheets/main/_typeset.scss","src/templates/assets/stylesheets/utilities/_break.scss","src/templates/assets/stylesheets/main/components/_author.scss","src/templates/assets/stylesheets/main/components/_banner.scss","src/templates/assets/stylesheets/main/components/_base.scss","src/templates/assets/stylesheets/main/components/_clipboard.scss","src/templates/assets/stylesheets/main/components/_code.scss","src/templates/assets/stylesheets/main/components/_consent.scss","src/templates/assets/stylesheets/main/components/_content.scss","src/templates/assets/stylesheets/main/components/_dialog.scss","src/templates/assets/stylesheets/main/components/_feedback.scss","src/templates/assets/stylesheets/main/components/_footer.scss","src/templates/assets/stylesheets/main/components/_form.scss","src/templates/assets/stylesheets/main/components/_header.scss","node_modules/material-design-color/material-color.scss","src/templates/assets/stylesheets/main/components/_nav.scss","src/templates/assets/stylesheets/main/components/_pagination.scss","src/templates/assets/stylesheets/main/components/_post.scss","src/templates/assets/stylesheets/main/components/_progress.scss","src/templates/assets/stylesheets/main/components/_search.scss","src/templates/assets/stylesheets/main/components/_select.scss","src/templates/assets/stylesheets/main/components/_sidebar.scss","src/templates/assets/stylesheets/main/components/_source.scss","src/templates/assets/stylesheets/main/components/_status.scss","src/templates/assets/stylesheets/main/components/_tabs.scss","src/templates/assets/stylesheets/main/components/_tag.scss","src/templates/assets/stylesheets/main/components/_tooltip.scss","src/templates/assets/stylesheets/main/components/_tooltip2.scss","src/templates/assets/stylesheets/main/components/_top.scss","src/templates/assets/stylesheets/main/components/_version.scss","src/templates/assets/stylesheets/main/extensions/markdown/_admonition.scss","src/templates/assets/stylesheets/main/extensions/markdown/_footnotes.scss","src/templates/assets/stylesheets/main/extensions/markdown/_toc.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_critic.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_details.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_emoji.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_highlight.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_keys.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss","src/templates/assets/stylesheets/main/integrations/_giscus.scss","src/templates/assets/stylesheets/main/integrations/_mermaid.scss","src/templates/assets/stylesheets/main/modifiers/_grid.scss","src/templates/assets/stylesheets/main/modifiers/_inline.scss"],"names":[],"mappings":"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,4DACE,oBlC05GJ,CkCv5GI,sFACE,gClCy5GN,CkCp5GE,oEACE,0BlCu5GJ,CkCp5GI,kFACE,wBAlBG,CAmBH,qDAAA,CAAA,6ClCs5GN,CkCl5GI,gFACE,alCo5GN,CkCz6GE,4DACE,oBlC46GJ,CkCz6GI,sFACE,gClC26GN,CkCt6GE,oEACE,0BlCy6GJ,CkCt6GI,kFACE,wBAlBG,CAmBH,qDAAA,CAAA,6ClCw6GN,CkCp6GI,gFACE,alCs6GN,CkC37GE,0DACE,oBlC87GJ,CkC37GI,oFACE,gClC67GN,CkCx7GE,kEACE,0BlC27GJ,CkCx7GI,gFACE,wBAlBG,CAmBH,oDAAA,CAAA,4ClC07GN,CkCt7GI,8EACE,alCw7GN,CkC78GE,oDACE,oBlCg9GJ,CkC78GI,8EACE,gClC+8GN,CkC18GE,4DACE,0BlC68GJ,CkC18GI,0EACE,wBAlBG,CAmBH,iDAAA,CAAA,yClC48GN,CkCx8GI,wEACE,alC08GN,CkC/9GE,4DACE,oBlCk+GJ,CkC/9GI,sFACE,gClCi+GN,CkC59GE,oEACE,0BlC+9GJ,CkC59GI,kFACE,wBAlBG,CAmBH,qDAAA,CAAA,6ClC89GN,CkC19GI,gFACE,alC49GN,CkCj/GE,wDACE,oBlCo/GJ,CkCj/GI,kFACE,gClCm/GN,CkC9+GE,gEACE,0BlCi/GJ,CkC9+GI,8EACE,wBAlBG,CAmBH,mDAAA,CAAA,2ClCg/GN,CkC5+GI,4EACE,alC8+GN,CmClpHA,MACE,qMnCqpHF,CmC5oHE,sBAEE,uCAAA,CADA,gBnCgpHJ,CmC5oHI,mCACE,anC8oHN,CmC/oHI,mCACE,cnC8oHN,CmC1oHM,4BACE,sBnC4oHR,CmCzoHQ,mCACE,gCnC2oHV,CmCvoHQ,2DACE,SAAA,CAEA,uBAAA,CADA,enC0oHV,CmCroHQ,yGACE,SAAA,CACA,uBnCuoHV,CmCnoHQ,yCACE,YnCqoHV,CmC9nHE,0BACE,eAAA,CACA,enCgoHJ,CmC7nHI,+BACE,oBnC+nHN,CmC1nHE,gDACE,YnC4nHJ,CmCxnHE,8BAIE,+BAAA,CAHA,oBAAA,CAEA,WAAA,CAGA,SAAA,CAKA,4B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","file":"main.css"} \ No newline at end of file diff --git a/main/assets/stylesheets/main.6f8fc17f.min.css b/main/assets/stylesheets/main.6f8fc17f.min.css new file mode 100644 index 000000000..a0d06b0eb --- /dev/null +++ b/main/assets/stylesheets/main.6f8fc17f.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-scheme=default]{color-scheme:light}[data-md-color-scheme=default] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=default] img[src$="#only-dark"]{display:none}:root,[data-md-color-scheme=default]{--md-hue:225deg;--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008a;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#00000012;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-hl-color:#4287ff;--md-code-hl-color--light:#4287ff1a;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-mark-color:#ffff0080;--md-typeset-table-color:#0000001f;--md-typeset-table-color--light:rgba(0,0,0,.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-warning-fg-color:#000000de;--md-warning-bg-color:#ff9;--md-footer-fg-color:#fff;--md-footer-fg-color--light:#ffffffb3;--md-footer-fg-color--lighter:#ffffff73;--md-footer-bg-color:#000000de;--md-footer-bg-color--dark:#00000052;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset h5 code{text-transform:none}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent)}.md-typeset a code{color:currentcolor;transition:background-color 125ms}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}.md-typeset ul[type]{list-style-type:revert-layer}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}.md-typeset ol ol ol ol,.md-typeset ul ol ol ol{list-style-type:upper-alpha}.md-typeset ol ol ol ol ol,.md-typeset ul ol ol ol ol{list-style-type:upper-roman}.md-typeset ol[type],.md-typeset ul[type]{list-style-type:revert-layer}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}[dir=ltr] .md-typeset ol li ol,[dir=ltr] .md-typeset ol li ul,[dir=ltr] .md-typeset ul li ol,[dir=ltr] .md-typeset ul li ul{margin-left:.625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block;margin:0 auto}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td>:first-child,.md-typeset table:not([class]) th>:first-child{margin-top:0}.md-typeset table:not([class]) td>:last-child,.md-typeset table:not([class]) th>:last-child{margin-bottom:0}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:var(--md-typeset-table-color--light);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.984375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-typeset .md-author{border-radius:100%;display:block;flex-shrink:0;height:1.6rem;overflow:hidden;position:relative;transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .md-author img{display:block}.md-typeset .md-author--more{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .md-author--long{height:2.4rem;width:2.4rem}.md-typeset a.md-author{transform:scale(1)}.md-typeset a.md-author img{border-radius:100%;filter:grayscale(100%) opacity(75%);transition:filter 125ms}.md-typeset a.md-author:focus,.md-typeset a.md-author:hover{transform:scale(1.1);z-index:1}.md-typeset a.md-author:focus img,.md-typeset a.md-author:hover img{filter:grayscale(0)}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background-color:var(--md-warning-bg-color);color:var(--md-warning-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.no-js .md-banner__button{display:none}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.984375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;position:absolute;right:.5em;top:.5em;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:focus,.md-clipboard:hover{color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:focus code,.md-clipboard--inline:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .md-code__content{display:grid}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:#0000008a;height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.984375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{display:flex;flex-wrap:wrap;place-content:baseline center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}@media print{.md-feedback{display:none}}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{align-items:end;display:flex;flex-grow:0.01;margin-bottom:.4rem;margin-top:1rem;max-width:100%;outline-color:var(--md-accent-fg-color);overflow:hidden;transition:opacity .25s}.md-footer__link:focus,.md-footer__link:hover{opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.984375em){.md-footer__link--prev{flex-shrink:0}.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;margin-bottom:.7rem;max-width:calc(100% - 2.4rem);padding:0 1rem;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;opacity:.7}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:focus,html .md-footer-meta.md-typeset a:hover{color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{display:inline-flex;gap:.2rem;margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:focus,.md-typeset .md-button:hover{background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:focus,.md-typeset .md-input:hover{border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem #0000,0 .2rem .4rem #0000;color:var(--md-primary-bg-color);display:block;left:0;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.234375em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo img,.md-header__button.md-logo svg{fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-left:1rem;margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem;margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__option>input{bottom:0}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}.md-meta{color:var(--md-default-fg-color--light);font-size:.7rem;line-height:1.3}.md-meta__list{display:inline-flex;flex-wrap:wrap;list-style:none;margin:0;padding:0}.md-meta__item:not(:last-child):after{content:"·";margin-left:.2rem;margin-right:.2rem}.md-meta__link{color:var(--md-typeset-a-color)}.md-meta__link:focus,.md-meta__link:hover{color:var(--md-accent-fg-color)}.md-draft{background-color:#ff1744;border-radius:.125em;color:#fff;display:inline-block;font-weight:700;padding-left:.5714285714em;padding-right:.5714285714em}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{color:var(--md-default-fg-color--light);display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo img,.md-nav__title .md-nav__button.md-logo svg{fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__link{align-items:flex-start;display:flex;gap:.4rem;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active,.md-nav__item .md-nav__link--active code{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{position:relative}[dir=ltr] .md-nav__link .md-icon:last-child{margin-left:auto}[dir=rtl] .md-nav__link .md-icon:last-child{margin-right:auto}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em;position:relative}.md-nav__link[for]:focus,.md-nav__link[for]:hover,.md-nav__link[href]:focus,.md-nav__link[href]:hover{color:var(--md-accent-fg-color);cursor:pointer}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1;min-width:0}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.234375em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary .md-nav__item,.md-nav--primary .md-nav__title{font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest)}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:focus,.md-nav--primary .md-nav__item--active>.md-nav__link:hover{color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link svg{margin-top:.1em}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.984375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav{margin-bottom:-.4rem}.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--secondary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--secondary .md-nav__list{padding-right:.6rem}.md-nav--secondary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--secondary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--secondary .md-nav__item>.md-nav__link{margin-left:.4rem}}@media screen and (min-width:76.25em){.md-nav{margin-bottom:-.4rem;transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--primary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--primary .md-nav__list{padding-right:.6rem}.md-nav--primary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--primary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--primary .md-nav__item>.md-nav__link{margin-left:.4rem}.md-nav__toggle~.md-nav{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .25s,visibility 0ms .25s;visibility:collapse}.md-nav__toggle~.md-nav>.md-nav__list{overflow:hidden}.md-nav__toggle.md-toggle--indeterminate~.md-nav,.md-nav__toggle:checked~.md-nav{grid-template-rows:1fr;opacity:1;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .15s .1s,visibility 0ms;visibility:visible}.md-nav__toggle.md-toggle--indeterminate~.md-nav{transition:none}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link[for]{color:var(--md-default-fg-color--light)}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-icon,.md-nav__item--section>.md-nav__link>[for]{display:none}[dir=ltr] .md-nav__item--section>.md-nav{margin-left:-.6rem}[dir=rtl] .md-nav__item--section>.md-nav{margin-right:-.6rem}.md-nav__item--section>.md-nav{display:block;opacity:1;visibility:visible}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s;width:.9rem}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;border-radius:100%;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;vertical-align:-.1rem;width:100%}[dir=rtl] .md-nav__icon:after{transform:rotate(180deg)}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon:after,.md-nav__item--nested .md-toggle--indeterminate~.md-nav__link .md-nav__icon:after{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);margin-top:0;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active.md-nav__item--section{margin:0}[dir=ltr] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-left:-.6rem}[dir=rtl] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-right:-.6rem}.md-nav--lifted>.md-nav__list>.md-nav__item>[for]{color:var(--md-default-fg-color--light)}.md-nav--lifted .md-nav[data-md-level="1"]{grid-template-rows:1fr;opacity:1;visibility:visible}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__list{overflow:visible;padding-bottom:0}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}.md-pagination{font-size:.8rem;font-weight:700;gap:.4rem}.md-pagination,.md-pagination>*{align-items:center;display:flex;justify-content:center}.md-pagination>*{border-radius:.2rem;height:1.8rem;min-width:1.8rem;text-align:center}.md-pagination__current{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light)}.md-pagination__link{transition:color 125ms,background-color 125ms}.md-pagination__link:focus,.md-pagination__link:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-pagination__link:focus svg,.md-pagination__link:hover svg{color:var(--md-accent-fg-color)}.md-pagination__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-pagination__link svg{fill:currentcolor;color:var(--md-default-fg-color--lighter);display:block;max-height:100%;width:1.2rem}.md-post__back{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin-bottom:1.2rem;padding-bottom:1.2rem}@media screen and (max-width:76.234375em){.md-post__back{display:none}}[dir=rtl] .md-post__back svg{transform:scaleX(-1)}.md-post__authors{display:flex;flex-direction:column;gap:.6rem;margin:0 .6rem 1.2rem}.md-post .md-post__meta a{transition:color 125ms}.md-post .md-post__meta a:focus,.md-post .md-post__meta a:hover{color:var(--md-accent-fg-color)}.md-post__title{color:var(--md-default-fg-color--light);font-weight:700}.md-post--excerpt{margin-bottom:3.2rem}.md-post--excerpt .md-post__header{align-items:center;display:flex;gap:.6rem;min-height:1.6rem}.md-post--excerpt .md-post__authors{align-items:center;display:inline-flex;flex-direction:row;gap:.2rem;margin:0;min-height:2.4rem}[dir=ltr] .md-post--excerpt .md-post__meta .md-meta__list{margin-right:.4rem}[dir=rtl] .md-post--excerpt .md-post__meta .md-meta__list{margin-left:.4rem}.md-post--excerpt .md-post__content>:first-child{--md-scroll-margin:6rem;margin-top:0}.md-post>.md-nav--secondary{margin:1em 0}.md-profile{align-items:center;display:flex;font-size:.7rem;gap:.6rem;line-height:1.4;width:100%}.md-profile__description{flex-grow:1}.md-content--post{display:flex}@media screen and (max-width:76.234375em){.md-content--post{flex-flow:column-reverse}}.md-content--post>.md-content__inner{min-width:0}@media screen and (min-width:76.25em){[dir=ltr] .md-content--post>.md-content__inner{margin-left:1.2rem}[dir=rtl] .md-content--post>.md-content__inner{margin-right:1.2rem}}@media screen and (max-width:76.234375em){.md-sidebar.md-sidebar--post{padding:0;position:static;width:100%}.md-sidebar.md-sidebar--post .md-sidebar__scrollwrap{overflow:visible}.md-sidebar.md-sidebar--post .md-sidebar__inner{padding:0}.md-sidebar.md-sidebar--post .md-post__meta{margin-left:.6rem;margin-right:.6rem}.md-sidebar.md-sidebar--post .md-nav__item{border:none;display:inline}.md-sidebar.md-sidebar--post .md-nav__list{display:inline-flex;flex-wrap:wrap;gap:.6rem;padding-bottom:.6rem;padding-top:.6rem}.md-sidebar.md-sidebar--post .md-nav__link{padding:0}.md-sidebar.md-sidebar--post .md-nav{height:auto;margin-bottom:0;position:static}}:root{--md-progress-value:0;--md-progress-delay:400ms}.md-progress{background:var(--md-primary-bg-color);height:.075rem;opacity:min(clamp(0,var(--md-progress-value),1),clamp(0,100 - var(--md-progress-value),1));position:fixed;top:0;transform:scaleX(calc(var(--md-progress-value)*1%));transform-origin:left;transition:transform .5s cubic-bezier(.19,1,.22,1),opacity .25s var(--md-progress-delay);width:100%;z-index:4}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:#0000008a;cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__inner{float:right}[dir=rtl] .md-search__inner{float:left}.md-search__inner{padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}}@media screen and (min-width:60em) and (max-width:76.234375em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem #0000;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:#00000042;border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:#ffffff1f}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem #00000012;color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:#0000;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::placeholder{transition:color .25s}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.984375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:#0000}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>.md-icon{margin-left:.2rem}[dir=rtl] .md-search__options>.md-icon{margin-right:.2rem}.md-search__options>.md-icon{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>.md-icon:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.984375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:focus,.md-search-result__link:hover{background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more>summary{cursor:pointer;display:block;outline:none;position:sticky;scroll-snap-align:start;top:0;z-index:1}.md-search-result__more>summary::marker{display:none}.md-search-result__more>summary::-webkit-details-marker{display:none}.md-search-result__more>summary>div{color:var(--md-typeset-a-color);font-size:.64rem;padding:.75em .8rem;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more>summary>div{padding-left:2.2rem}[dir=rtl] .md-search-result__more>summary>div{padding-right:2.2rem}}.md-search-result__more>summary:focus>div,.md-search-result__more>summary:hover>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more[open]>summary{background-color:var(--md-default-bg-color)}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.984375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result .md-typeset{color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.6}.md-search-result .md-typeset h1{color:var(--md-default-fg-color);font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}.md-search-result .md-typeset h1 mark{text-decoration:none}.md-search-result .md-typeset h2{color:var(--md-default-fg-color);font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result .md-typeset h2 mark{text-decoration:none}.md-search-result__terms{color:var(--md-default-fg-color);display:block;font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color);text-decoration:underline}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:focus,.md-select__link:hover{color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.234375em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{scrollbar-gutter:stable;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap:focus-within,.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}}@media screen and (max-width:76.234375em){.md-overlay{background-color:#0000008a;height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-source-file{margin:1em 0}[dir=ltr] .md-source-file__fact{margin-right:.6rem}[dir=rtl] .md-source-file__fact{margin-left:.6rem}.md-source-file__fact{align-items:center;color:var(--md-default-fg-color--light);display:inline-flex;font-size:.68rem;gap:.3rem}.md-source-file__fact .md-icon{flex-shrink:0;margin-bottom:.05rem}[dir=ltr] .md-source-file__fact .md-author{float:left}[dir=rtl] .md-source-file__fact .md-author{float:right}.md-source-file__fact .md-author{margin-right:.2rem}.md-source-file__fact svg{width:.9rem}:root{--md-status:url('data:image/svg+xml;charset=utf-8,');--md-status--new:url('data:image/svg+xml;charset=utf-8,');--md-status--deprecated:url('data:image/svg+xml;charset=utf-8,');--md-status--encrypted:url('data:image/svg+xml;charset=utf-8,')}.md-status:after{background-color:var(--md-default-fg-color--light);content:"";display:inline-block;height:1.125em;-webkit-mask-image:var(--md-status);mask-image:var(--md-status);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.125em}.md-status:hover:after{background-color:currentcolor}.md-status--new:after{-webkit-mask-image:var(--md-status--new);mask-image:var(--md-status--new)}.md-status--deprecated:after{-webkit-mask-image:var(--md-status--deprecated);mask-image:var(--md-status--deprecated)}.md-status--encrypted:after{-webkit-mask-image:var(--md-status--encrypted);mask-image:var(--md-status--encrypted)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.234375em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;list-style:none;margin:0;overflow:auto;padding:0;scrollbar-width:none;white-space:nowrap}.md-tabs__list::-webkit-scrollbar{display:none}.md-tabs__item{height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__item--active .md-tabs__link{color:inherit;opacity:1}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link:focus,.md-tabs__link:hover{color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags:not([hidden]){display:inline-flex;flex-wrap:wrap;gap:.5em;margin-bottom:.75em;margin-top:-.125em}.md-typeset .md-tag{align-items:center;background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-flex;font-size:.64rem;font-size:min(.8em,.64rem);font-weight:700;gap:.5em;letter-spacing:normal;line-height:1.6;padding:.3125em .78125em}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon[href]:focus:before,.md-typeset .md-tag-icon[href]:hover:before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{transform:scale(.95)}75%{transform:scale(1)}to{transform:scale(.95)}}:root{--md-annotation-bg-icon:url('data:image/svg+xml;charset=utf-8,');--md-annotation-icon:url('data:image/svg+xml;charset=utf-8,')}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}.focus-visible>.md-tooltip,.md-tooltip:target{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-style:normal;font-weight:400;outline:none;text-align:initial;vertical-align:text-bottom;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}code .md-annotation{font-family:var(--md-code-font-family);font-size:inherit}.md-annotation:not([hidden]){display:inline-block;line-height:1.25}.md-annotation__index{border-radius:.01px;cursor:pointer;display:inline-block;margin-left:.4ch;margin-right:.4ch;outline:none;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none;vertical-align:text-top;z-index:0}.md-annotation .md-annotation__index{transition:z-index .25s}@media screen{.md-annotation__index{width:2.2ch}[data-md-visible]>.md-annotation__index{animation:pulse 2s infinite}.md-annotation__index:before{background:var(--md-default-bg-color);-webkit-mask-image:var(--md-annotation-bg-icon);mask-image:var(--md-annotation-bg-icon)}.md-annotation__index:after,.md-annotation__index:before{content:"";height:2.2ch;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:-.1ch;width:2.2ch;z-index:-1}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);-webkit-mask-image:var(--md-annotation-icon);mask-image:var(--md-annotation-icon);transform:scale(1.0001);transition:background-color .25s,transform .25s}.md-tooltip--active+.md-annotation__index:after{transform:rotate(45deg)}.md-tooltip--active+.md-annotation__index:after,:hover>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}}.md-tooltip--active+.md-annotation__index{animation-play-state:paused;transition-duration:0ms;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block}@media print{.md-annotation__index [data-md-annotation-id]{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);font-weight:700;padding:0 .6ch;white-space:nowrap}.md-annotation__index [data-md-annotation-id]:after{content:attr(data-md-annotation-id)}}.md-typeset .md-annotation-list{counter-reset:xxx;list-style:none}.md-typeset .md-annotation-list li{position:relative}[dir=ltr] .md-typeset .md-annotation-list li:before{left:-2.125em}[dir=rtl] .md-typeset .md-annotation-list li:before{right:-2.125em}.md-typeset .md-annotation-list li:before{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);content:counter(xxx);counter-increment:xxx;font-size:.8875em;font-weight:700;height:2ch;line-height:1.25;min-width:2ch;padding:0 .6ch;position:absolute;text-align:center;top:.25em}:root{--md-tooltip-width:20rem;--md-tooltip-tail:0.3rem}.md-tooltip2{-webkit-backface-visibility:hidden;backface-visibility:hidden;color:var(--md-default-fg-color);font-family:var(--md-text-font-family);opacity:0;pointer-events:none;position:absolute;top:calc(var(--md-tooltip-host-y) + var(--md-tooltip-y));transform:translateY(-.4rem);transform-origin:calc(var(--md-tooltip-host-x) + var(--md-tooltip-x)) 0;transition:transform 0ms .25s,opacity .25s,z-index .25s;width:100%;z-index:0}.md-tooltip2:before{border-left:var(--md-tooltip-tail) solid #0000;border-right:var(--md-tooltip-tail) solid #0000;content:"";display:block;left:clamp(1.5 * .8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-tail),100vw - 2 * var(--md-tooltip-tail) - 1.5 * .8rem);position:absolute;z-index:1}.md-tooltip2--top:before{border-top:var(--md-tooltip-tail) solid var(--md-default-bg-color);bottom:calc(var(--md-tooltip-tail)*-1 + .025rem);filter:drop-shadow(0 1px 0 hsla(0,0%,0%,.05))}.md-tooltip2--bottom:before{border-bottom:var(--md-tooltip-tail) solid var(--md-default-bg-color);filter:drop-shadow(0 -1px 0 hsla(0,0%,0%,.05));top:calc(var(--md-tooltip-tail)*-1 + .025rem)}.md-tooltip2--active{opacity:1;transform:translateY(0);transition:transform .4s cubic-bezier(0,1,.5,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip2__inner{scrollbar-gutter:stable;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);left:clamp(.8rem,var(--md-tooltip-host-x) - .8rem,100vw - var(--md-tooltip-width) - .8rem);max-height:40vh;max-width:calc(100vw - 1.6rem);position:relative;scrollbar-width:thin}.md-tooltip2__inner::-webkit-scrollbar{height:.2rem;width:.2rem}.md-tooltip2__inner::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-tooltip2__inner::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}[role=tooltip]>.md-tooltip2__inner{font-size:.5rem;font-weight:700;left:clamp(.8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-width)/2,100vw - var(--md-tooltip-width) - .8rem);max-width:min(100vw - 2 * .8rem,400px);padding:.2rem .4rem;-webkit-user-select:none;user-select:none;width:-moz-fit-content;width:fit-content}.md-tooltip2__inner.md-typeset>:first-child{margin-top:0}.md-tooltip2__inner.md-typeset>:last-child{margin-bottom:0}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:focus,.md-top:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__alias{margin-left:.3rem;opacity:.7}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:focus-within .md-version__list,.md-version:hover .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (hover:none),(pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:focus,.md-version__link:hover{color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:var(--md-admonition-bg-color);border:.075rem solid #448aff;border-radius:.2rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid;transition:box-shadow 125ms}@media print{.md-typeset .admonition,.md-typeset details{box-shadow:none}}.md-typeset .admonition:focus-within,.md-typeset details:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:2rem;padding-right:.6rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.6rem;padding-right:2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-left-width:.2rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-right-width:.2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset .admonition-title,.md-typeset summary{background-color:#448aff1a;border:none;font-weight:700;margin:0 -.6rem;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset .admonition-title:last-child,html .md-typeset summary:last-child{margin-bottom:0}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:.6rem}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:.6rem}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset .admonition-title code,.md-typeset summary code{box-shadow:0 0 0 .05rem var(--md-default-fg-color--lightest)}.md-typeset .admonition.note,.md-typeset details.note{border-color:#448aff}.md-typeset .admonition.note:focus-within,.md-typeset details.note:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .note>.admonition-title,.md-typeset .note>summary{background-color:#448aff1a}.md-typeset .note>.admonition-title:before,.md-typeset .note>summary:before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset .note>.admonition-title:after,.md-typeset .note>summary:after{color:#448aff}.md-typeset .admonition.abstract,.md-typeset details.abstract{border-color:#00b0ff}.md-typeset .admonition.abstract:focus-within,.md-typeset details.abstract:focus-within{box-shadow:0 0 0 .2rem #00b0ff1a}.md-typeset .abstract>.admonition-title,.md-typeset .abstract>summary{background-color:#00b0ff1a}.md-typeset .abstract>.admonition-title:before,.md-typeset .abstract>summary:before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset .abstract>.admonition-title:after,.md-typeset .abstract>summary:after{color:#00b0ff}.md-typeset .admonition.info,.md-typeset details.info{border-color:#00b8d4}.md-typeset .admonition.info:focus-within,.md-typeset details.info:focus-within{box-shadow:0 0 0 .2rem #00b8d41a}.md-typeset .info>.admonition-title,.md-typeset .info>summary{background-color:#00b8d41a}.md-typeset .info>.admonition-title:before,.md-typeset .info>summary:before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset .info>.admonition-title:after,.md-typeset .info>summary:after{color:#00b8d4}.md-typeset .admonition.tip,.md-typeset details.tip{border-color:#00bfa5}.md-typeset .admonition.tip:focus-within,.md-typeset details.tip:focus-within{box-shadow:0 0 0 .2rem #00bfa51a}.md-typeset .tip>.admonition-title,.md-typeset .tip>summary{background-color:#00bfa51a}.md-typeset .tip>.admonition-title:before,.md-typeset .tip>summary:before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset .tip>.admonition-title:after,.md-typeset .tip>summary:after{color:#00bfa5}.md-typeset .admonition.success,.md-typeset details.success{border-color:#00c853}.md-typeset .admonition.success:focus-within,.md-typeset details.success:focus-within{box-shadow:0 0 0 .2rem #00c8531a}.md-typeset .success>.admonition-title,.md-typeset .success>summary{background-color:#00c8531a}.md-typeset .success>.admonition-title:before,.md-typeset .success>summary:before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset .success>.admonition-title:after,.md-typeset .success>summary:after{color:#00c853}.md-typeset .admonition.question,.md-typeset details.question{border-color:#64dd17}.md-typeset .admonition.question:focus-within,.md-typeset details.question:focus-within{box-shadow:0 0 0 .2rem #64dd171a}.md-typeset .question>.admonition-title,.md-typeset .question>summary{background-color:#64dd171a}.md-typeset .question>.admonition-title:before,.md-typeset .question>summary:before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset .question>.admonition-title:after,.md-typeset .question>summary:after{color:#64dd17}.md-typeset .admonition.warning,.md-typeset details.warning{border-color:#ff9100}.md-typeset .admonition.warning:focus-within,.md-typeset details.warning:focus-within{box-shadow:0 0 0 .2rem #ff91001a}.md-typeset .warning>.admonition-title,.md-typeset .warning>summary{background-color:#ff91001a}.md-typeset .warning>.admonition-title:before,.md-typeset .warning>summary:before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset .warning>.admonition-title:after,.md-typeset .warning>summary:after{color:#ff9100}.md-typeset .admonition.failure,.md-typeset details.failure{border-color:#ff5252}.md-typeset .admonition.failure:focus-within,.md-typeset details.failure:focus-within{box-shadow:0 0 0 .2rem #ff52521a}.md-typeset .failure>.admonition-title,.md-typeset .failure>summary{background-color:#ff52521a}.md-typeset .failure>.admonition-title:before,.md-typeset .failure>summary:before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset .failure>.admonition-title:after,.md-typeset .failure>summary:after{color:#ff5252}.md-typeset .admonition.danger,.md-typeset details.danger{border-color:#ff1744}.md-typeset .admonition.danger:focus-within,.md-typeset details.danger:focus-within{box-shadow:0 0 0 .2rem #ff17441a}.md-typeset .danger>.admonition-title,.md-typeset .danger>summary{background-color:#ff17441a}.md-typeset .danger>.admonition-title:before,.md-typeset .danger>summary:before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset .danger>.admonition-title:after,.md-typeset .danger>summary:after{color:#ff1744}.md-typeset .admonition.bug,.md-typeset details.bug{border-color:#f50057}.md-typeset .admonition.bug:focus-within,.md-typeset details.bug:focus-within{box-shadow:0 0 0 .2rem #f500571a}.md-typeset .bug>.admonition-title,.md-typeset .bug>summary{background-color:#f500571a}.md-typeset .bug>.admonition-title:before,.md-typeset .bug>summary:before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset .bug>.admonition-title:after,.md-typeset .bug>summary:after{color:#f50057}.md-typeset .admonition.example,.md-typeset details.example{border-color:#7c4dff}.md-typeset .admonition.example:focus-within,.md-typeset details.example:focus-within{box-shadow:0 0 0 .2rem #7c4dff1a}.md-typeset .example>.admonition-title,.md-typeset .example>summary{background-color:#7c4dff1a}.md-typeset .example>.admonition-title:before,.md-typeset .example>summary:before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset .example>.admonition-title:after,.md-typeset .example>summary:after{color:#7c4dff}.md-typeset .admonition.quote,.md-typeset details.quote{border-color:#9e9e9e}.md-typeset .admonition.quote:focus-within,.md-typeset details.quote:focus-within{box-shadow:0 0 0 .2rem #9e9e9e1a}.md-typeset .quote>.admonition-title,.md-typeset .quote>summary{background-color:#9e9e9e1a}.md-typeset .quote>.admonition-title:before,.md-typeset .quote>summary:before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset .quote>.admonition-title:after,.md-typeset .quote>summary:after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:hover .footnote-backref,.md-typeset .footnote>ol>li:target .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :hover>.headerlink,.md-typeset :target>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset .headerlink:hover,.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset h1:target,.md-typeset h2:target,.md-typeset h3:target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.984375em){.md-typeset div.arithmatex{margin:0 -.8rem}.md-typeset div.arithmatex>*{width:min-content}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset div.arithmatex mjx-assistive-mml{height:0}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset del.critic,.md-typeset ins.critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem;overflow:hidden}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset .emojione,.md-typeset .gemoji,.md-typeset .twemoji{--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset .emojione svg,.md-typeset .gemoji svg,.md-typeset .twemoji svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset .lg,.md-typeset .xl,.md-typeset .xxl,.md-typeset .xxxl{vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight .o,.highlight .ow{color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight .cpf,.highlight .l,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .si,.highlight .ss{color:var(--md-code-hl-string-color)}.highlight .cp,.highlight .se,.highlight .sh,.highlight .sr,.highlight .sx{color:var(--md-code-hl-special-color)}.highlight .il,.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--md-code-hl-number-color)}.highlight .k,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:var(--md-code-hl-keyword-color)}.highlight .kc,.highlight .n{color:var(--md-code-hl-name-color)}.highlight .bp,.highlight .nb,.highlight .no{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight .ne,.highlight .nf,.highlight .nn{color:var(--md-code-hl-function-color)}.highlight .nd,.highlight .ni,.highlight .nl,.highlight .nt{color:var(--md-code-hl-keyword-color)}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm,.highlight .cs,.highlight .sd{color:var(--md-code-hl-comment-color)}.highlight .na,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--md-code-hl-variable-color)}.highlight .ge,.highlight .gh,.highlight .go,.highlight .gp,.highlight .gr,.highlight .gs,.highlight .gt,.highlight .gu{color:var(--md-code-hl-generic-color)}.highlight .gd,.highlight .gi{border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color--light);box-shadow:2px 0 0 0 var(--md-code-hl-color) inset;display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:sticky;-webkit-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying]{display:initial}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable tbody,.highlighttable td{display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;padding-right:.5882352941em}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.984375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:after,.md-typeset .keys kbd:before{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-set>input.focus-visible~.tabbed-labels:before{background-color:var(--md-accent-fg-color)}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-default-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,background-color .25s,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-default-fg-color)}.md-typeset .tabbed-labels>label>[href]:first-child{color:inherit}.md-typeset .tabbed-labels--linked>label{padding:0}.md-typeset .tabbed-labels--linked>label>a{display:block;padding:.78125em 1.25em .625em}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,#0000);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,#0000);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.984375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-default-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-default-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}@media print{.giscus,[id=__comments]{display:none}}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color);--md-mermaid-sequence-actor-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actor-fg-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-actor-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-actor-line-color:var(--md-default-fg-color--lighter);--md-mermaid-sequence-actorman-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actorman-line-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-box-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-box-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-label-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-label-fg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-loop-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-loop-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-loop-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-message-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-message-line-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-note-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-border-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-number-bg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-number-fg-color:var(--md-accent-bg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr));margin:1em 0}.md-typeset .grid.cards>ol,.md-typeset .grid.cards>ul{display:contents}.md-typeset .grid.cards>ol>li,.md-typeset .grid.cards>ul>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>ol>li:focus-within,.md-typeset .grid.cards>ol>li:hover,.md-typeset .grid.cards>ul>li:focus-within,.md-typeset .grid.cards>ul>li:hover,.md-typeset .grid>.card:focus-within,.md-typeset .grid>.card:hover{border-color:#0000;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>ol>li>hr,.md-typeset .grid.cards>ul>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>ol>li>:first-child,.md-typeset .grid.cards>ul>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>ol>li>:last-child,.md-typeset .grid.cards>ul>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*,.md-typeset .grid>.admonition,.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>.md-typeset details,.md-typeset .grid>details,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/main/assets/stylesheets/main.6f8fc17f.min.css.map b/main/assets/stylesheets/main.6f8fc17f.min.css.map new file mode 100644 index 000000000..8ba5ce39e --- /dev/null +++ b/main/assets/stylesheets/main.6f8fc17f.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/templates/assets/stylesheets/main/components/_meta.scss","../../../../src/templates/assets/stylesheets/main.scss","src/templates/assets/stylesheets/main/_resets.scss","src/templates/assets/stylesheets/main/_colors.scss","src/templates/assets/stylesheets/main/_icons.scss","src/templates/assets/stylesheets/main/_typeset.scss","src/templates/assets/stylesheets/utilities/_break.scss","src/templates/assets/stylesheets/main/components/_author.scss","src/templates/assets/stylesheets/main/components/_banner.scss","src/templates/assets/stylesheets/main/components/_base.scss","src/templates/assets/stylesheets/main/components/_clipboard.scss","src/templates/assets/stylesheets/main/components/_code.scss","src/templates/assets/stylesheets/main/components/_consent.scss","src/templates/assets/stylesheets/main/components/_content.scss","src/templates/assets/stylesheets/main/components/_dialog.scss","src/templates/assets/stylesheets/main/components/_feedback.scss","src/templates/assets/stylesheets/main/components/_footer.scss","src/templates/assets/stylesheets/main/components/_form.scss","src/templates/assets/stylesheets/main/components/_header.scss","node_modules/material-design-color/material-color.scss","src/templates/assets/stylesheets/main/components/_nav.scss","src/templates/assets/stylesheets/main/components/_pagination.scss","src/templates/assets/stylesheets/main/components/_post.scss","src/templates/assets/stylesheets/main/components/_progress.scss","src/templates/assets/stylesheets/main/components/_search.scss","src/templates/assets/stylesheets/main/components/_select.scss","src/templates/assets/stylesheets/main/components/_sidebar.scss","src/templates/assets/stylesheets/main/components/_source.scss","src/templates/assets/stylesheets/main/components/_status.scss","src/templates/assets/stylesheets/main/components/_tabs.scss","src/templates/assets/stylesheets/main/components/_tag.scss","src/templates/assets/stylesheets/main/components/_tooltip.scss","src/templates/assets/stylesheets/main/components/_tooltip2.scss","src/templates/assets/stylesheets/main/components/_top.scss","src/templates/assets/stylesheets/main/components/_version.scss","src/templates/assets/stylesheets/main/extensions/markdown/_admonition.scss","src/templates/assets/stylesheets/main/extensions/markdown/_footnotes.scss","src/templates/assets/stylesheets/main/extensions/markdown/_toc.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_critic.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_details.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_emoji.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_highlight.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_keys.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss","src/templates/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss","src/templates/assets/stylesheets/main/integrations/_giscus.scss","src/templates/assets/stylesheets/main/integrations/_mermaid.scss","src/templates/assets/stylesheets/main/modifiers/_grid.scss","src/templates/assets/stylesheets/main/modifiers/_inline.scss"],"names":[],"mappings":"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FACE,alCq4GN,CkC15GE,4DACE,oBlC65GJ,CkC15GI,sFACE,gClC45GN,CkCv5GE,oEACE,0BlC05GJ,CkCv5GI,kFACE,wBAlBG,CAmBH,qDAAA,CAAA,6ClCy5GN,CkCr5GI,gFACE,alCu5GN,CkC56GE,4DACE,oBlC+6GJ,CkC56GI,sFACE,gClC86GN,CkCz6GE,oEACE,0BlC46GJ,CkCz6GI,kFACE,wBAlBG,CAmBH,qDAAA,CAAA,6ClC26GN,CkCv6GI,gFACE,alCy6GN,CkC97GE,0DACE,oBlCi8GJ,CkC97GI,oFACE,gClCg8GN,CkC37GE,kEACE,0BlC87GJ,CkC37GI,gFACE,wBAlBG,CAmBH,oDAAA,CAAA,4ClC67GN,CkCz7GI,8EACE,alC27GN,CkCh9GE,oDACE,oBlCm9GJ,CkCh9GI,8EACE,gClCk9GN,CkC78GE,4DACE,0BlCg9GJ,CkC78GI,0EACE,wBAlBG,CAmBH,iDAAA,CAAA,yClC+8GN,CkC38GI,wEACE,alC68GN,CkCl+GE,4DACE,oBlCq+GJ,CkCl+GI,sFACE,gClCo+GN,CkC/9GE,oEACE,0BlCk+GJ,CkC/9GI,kFACE,wBAlBG,CAmBH,qDAAA,CAAA,6ClCi+GN,CkC79GI,gFACE,alC+9GN,CkCp/GE,wDACE,oBlCu/GJ,CkCp/GI,kFACE,gClCs/GN,CkCj/GE,gEACE,0BlCo/GJ,CkCj/GI,8EACE,wBAlBG,CAmBH,mDAAA,CAAA,2ClCm/GN,CkC/+GI,4EACE,alCi/GN,CmCrpHA,MACE,qMnCwpHF,CmC/oHE,sBAEE,uCAAA,CADA,gBnCmpHJ,CmC/oHI,mCACE,anCipHN,CmClpHI,mCACE,cnCipHN,CmC7oHM,4BACE,sBnC+oHR,CmC5oHQ,mCACE,gCnC8oHV,CmC1oHQ,2DACE,SAAA,CAEA,uBAAA,CADA,enC6oHV,CmCxoHQ,yGACE,SAAA,CACA,uBnC0oHV,CmCtoHQ,yCACE,YnCwoHV,CmCjoHE,0BACE,eAAA,CACA,enCmoHJ,CmChoHI,+BACE,oBnCkoHN,CmC7nHE,gDACE,YnC+nHJ,CmC3nHE,8BAIE,+BAAA,CAHA,oBAAA,CAEA,WA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","file":"main.css"} \ No newline at end of file diff --git a/main/cicd/gh-action/index.html b/main/cicd/gh-action/index.html index cdd0b9429..cac5b6015 100644 --- a/main/cicd/gh-action/index.html +++ b/main/cicd/gh-action/index.html @@ -1,4 +1,4 @@ - GitHub action - Chainsaw
Skip to content

GitHub action

A GitHub action is available to easily install Chainsaw in your workflows.

The GitHub action is available at kyverno/action-install-chainsaw or in the marketplace.

Usage

This action currently supports GitHub-provided Linux, macOS and Windows runners (self-hosted runners may not work).

Add the following entry to your Github workflow YAML file:

uses: kyverno/action-install-chainsaw@v0.1.0
+ GitHub action - Chainsaw      

GitHub action

A GitHub action is available to easily install Chainsaw in your workflows.

The GitHub action is available at kyverno/action-install-chainsaw or in the marketplace.

Usage

This action currently supports GitHub-provided Linux, macOS and Windows runners (self-hosted runners may not work).

Add the following entry to your Github workflow YAML file:

uses: kyverno/action-install-chainsaw@v0.1.0
 with:
   release: v0.1.0 # optional
 

Example using a pinned version:

jobs:
@@ -61,4 +61,4 @@
           release: main
       - name: Check install
         run: chainsaw version
-

Optional Inputs

The following optional inputs:

Input Description
release chainsaw version to use instead of the default.
install-dir directory to place the chainsaw binary into instead of the default ($HOME/.chainsaw).
use-sudo set to true if install-dir location requires sudo privs. Defaults to false.
verify set to true to enable cosign verification of the downloaded archive.
\ No newline at end of file +

Optional Inputs

The following optional inputs:

Input Description
release chainsaw version to use instead of the default.
install-dir directory to place the chainsaw binary into instead of the default ($HOME/.chainsaw).
use-sudo set to true if install-dir location requires sudo privs. Defaults to false.
verify set to true to enable cosign verification of the downloaded archive.
\ No newline at end of file diff --git a/main/community/contribute/index.html b/main/community/contribute/index.html index 05adb4172..dc8882e89 100644 --- a/main/community/contribute/index.html +++ b/main/community/contribute/index.html @@ -1 +1 @@ - Contributing - Chainsaw
Skip to content

Contributing

Chainsaw, developed by Kyverno, is an advanced end-to-end testing tool for Kubernetes. Our community plays a crucial role in shaping the project by reporting bugs, suggesting features, and improving documentation.

We aim to make our issue tracker, discussion board, and documentation well-structured and easy to navigate. By following our guidelines, you can help us address your requests efficiently.

How you can contribute

We appreciate your efforts in reporting bugs, requesting features, and engaging in discussions. Here's how you can contribute:

Creating an issue

  •   Something is not working?


    Report a bug in Chainsaw by creating an issue with a reproduction


    Report a bug

  •   Missing information in our docs?


    Report missing information or potential inconsistencies in our documentation


    Report a docs issue

  •   Want to submit an idea?


    Propose a change, feature request, or suggest an improvement


    Request a change

  •   Have a question or need help?


    Ask a question on our discussion board and get in touch with our community


    Ask a question

Contributing

  •   Want to create a pull request?


    Learn how to create a comprehensive and useful pull request (PR)


    Create a pull request

Checklist

Before interacting within the project, please consider the following questions to ensure you're using the correct issue template and providing all necessary information.

Issues, discussions, and comments are forever

Please note that everything you write is permanent and will remain for everyone to read – forever. Therefore, please always be nice and constructive, follow our contribution guidelines, and comply with our Code of Conduct.

Before creating an issue

  • Are you using the appropriate issue template, or is there another issue template that better fits the context of your request?
  • Have you checked if a similar bug report or change request has already been created, or have you stumbled upon something that might be related?
  • Did you fill out every field as requested and provide all additional information needed to comprehend your request?

Before asking a question

  • Is the topic a question for our discussion board, or is it a bug report or change request that should be raised on our [issue tracker]?
  • Is there an open discussion on the topic of your request? If the answer is yes, does your question match the direction of the discussion, or should you open a new discussion?
  • Did you provide our community with all the necessary information to understand your question and help you quickly, or can you make it easier to help you?

Before commenting

  • Is your comment relevant to the topic of the current page, post, issue, or discussion, or is it better to create a new issue or discussion?
  • Does your comment add value to the conversation? Is it constructive and respectful to our community and maintainers? Could you just use a reaction instead?

Rights and responsibilities

As maintainers, we are entrusted with the responsibility to moderate communication within our community, including the authority to close, remove, reject, or edit issues, discussions, comments, commits, and to block users who do not align with our contribution guidelines and our Code of Conduct. This role requires us to be actively involved in maintaining the integrity and positive atmosphere of our community. Upholding these standards decisively ensures a respectful and inclusive environment for all members.

Code of Conduct

Our Code of Conduct outlines the expectation for all community members to treat one another with respect, employing inclusive and welcoming language. Our commitment is to foster a positive and supportive environment, free of inappropriate, offensive, or harmful behavior.

We take any violations seriously and will take appropriate action in response to uphold these values.1

Incomplete issues and duplicates

We have invested significant time and effort in the setup of our contribution process, ensuring that we assess the essential requirements for reviewing and responding to issues effectively. Each field in our issue templates is thoughtfully designed to help us fully understand your concerns and the nature of your matter. We encourage all members to utilize the search function before submitting new issues or starting discussions to help avoid duplicates. Your cooperation is crucial in keeping our community's discussions constructive and organized.

  • Mandatory completion of issue templates: We need all of the information required in our issue templates because it ensures that every user and maintainer, regardless of their experience, can understand the content and severity of your bug report or change request.

  • Closing incomplete issues: We reserve the right to close issues lacking essential information, such as but not limited to [minimal reproductions] or those not adhering to the quality standards and requirements specified in our issue templates. Such issues can be reopened once the missing information has been provided.

  • Handling duplicates: To maintain organized and efficient communication within our [issue tracker] and discussion board, we reserve the right to close any duplicated issues or lock duplicated discussions. Opening multiple channels to ask the same question or report the same issue across different forums hinders our ability to manage and address community concerns effectively. This approach is vital for efficient time management, as duplicated questions can consume the time of multiple team members simultaneously. Ensuring that each issue or discussion is unique and progresses with new information helps us to maintain focus and support our community.

    We further reserve the right to immediately close discussions or issues that are reopened without providing new information or simply because users have not yet received a response to their issue/question, as the issue is marked as incomplete.

  • Limitations of automated tools: While we believe in the value and efficiency that automated tools bring to identifying potential issues (such as those identified by Lighthouse, Accessibility tools, and others), simply submitting an issue generated by these tools does not constitute a complete bug report. These tools sometimes produce verbose outputs and may include false positives, which necessitate a critical evaluation. You are of course welcome to attach generated reports to your issue. However, this does not substitute the requirement for a minimal reproduction or a thorough discussion of the findings. We reserve the right to mark these issues as incomplete and close them. This practice ensures that we are addressing genuine concerns with precision and clarity, rather than navigating through extensive automated outputs.


  1. Warning and blocking policy: Given the increasing popularity of our project and our commitment to a healthy community, we've defined clear guidelines on how we proceed with violations:

    1.1. First warning: Users displaying repeated inappropriate, offensive, or harmful behavior will receive a first warning. This warning serves as a formal notice that their behavior is not in alignment with our community standards and Code of Conduct. The first warning is permanent.

    1.2. Second warning and opportunity for resolution: If the behavior persists, a second warning will be issued. Upon receiving the second warning, the user will be given a 5-day period for reflection, during which they are encouraged to publicly explain or apologize for their actions. This period is designed to offer an opportunity for openly clearing out any misunderstanding.

    1.3. Blocking: Should there be no response or improvement in behavior following the second warning, we reserve the right to block the user from the community and repository. Blocking is considered a last resort, used only when absolutely necessary to protect the community's integrity and positive atmosphere.

    Blocking has been an exceptionally rare necessity in our overwhelmingly positive community, highlighting our preference for constructive dialogue and mutual respect. It aims to protect our community members and team. 

\ No newline at end of file + Contributing - Chainsaw
Skip to content

Contributing

Chainsaw, developed by Kyverno, is an advanced end-to-end testing tool for Kubernetes. Our community plays a crucial role in shaping the project by reporting bugs, suggesting features, and improving documentation.

We aim to make our issue tracker, discussion board, and documentation well-structured and easy to navigate. By following our guidelines, you can help us address your requests efficiently.

How you can contribute

We appreciate your efforts in reporting bugs, requesting features, and engaging in discussions. Here's how you can contribute:

Creating an issue

  •   Something is not working?


    Report a bug in Chainsaw by creating an issue with a reproduction


    Report a bug

  •   Missing information in our docs?


    Report missing information or potential inconsistencies in our documentation


    Report a docs issue

  •   Want to submit an idea?


    Propose a change, feature request, or suggest an improvement


    Request a change

  •   Have a question or need help?


    Ask a question on our discussion board and get in touch with our community


    Ask a question

Contributing

  •   Want to create a pull request?


    Learn how to create a comprehensive and useful pull request (PR)


    Create a pull request

Checklist

Before interacting within the project, please consider the following questions to ensure you're using the correct issue template and providing all necessary information.

Issues, discussions, and comments are forever

Please note that everything you write is permanent and will remain for everyone to read – forever. Therefore, please always be nice and constructive, follow our contribution guidelines, and comply with our Code of Conduct.

Before creating an issue

  • Are you using the appropriate issue template, or is there another issue template that better fits the context of your request?
  • Have you checked if a similar bug report or change request has already been created, or have you stumbled upon something that might be related?
  • Did you fill out every field as requested and provide all additional information needed to comprehend your request?

Before asking a question

  • Is the topic a question for our discussion board, or is it a bug report or change request that should be raised on our [issue tracker]?
  • Is there an open discussion on the topic of your request? If the answer is yes, does your question match the direction of the discussion, or should you open a new discussion?
  • Did you provide our community with all the necessary information to understand your question and help you quickly, or can you make it easier to help you?

Before commenting

  • Is your comment relevant to the topic of the current page, post, issue, or discussion, or is it better to create a new issue or discussion?
  • Does your comment add value to the conversation? Is it constructive and respectful to our community and maintainers? Could you just use a reaction instead?

Rights and responsibilities

As maintainers, we are entrusted with the responsibility to moderate communication within our community, including the authority to close, remove, reject, or edit issues, discussions, comments, commits, and to block users who do not align with our contribution guidelines and our Code of Conduct. This role requires us to be actively involved in maintaining the integrity and positive atmosphere of our community. Upholding these standards decisively ensures a respectful and inclusive environment for all members.

Code of Conduct

Our Code of Conduct outlines the expectation for all community members to treat one another with respect, employing inclusive and welcoming language. Our commitment is to foster a positive and supportive environment, free of inappropriate, offensive, or harmful behavior.

We take any violations seriously and will take appropriate action in response to uphold these values.1

Incomplete issues and duplicates

We have invested significant time and effort in the setup of our contribution process, ensuring that we assess the essential requirements for reviewing and responding to issues effectively. Each field in our issue templates is thoughtfully designed to help us fully understand your concerns and the nature of your matter. We encourage all members to utilize the search function before submitting new issues or starting discussions to help avoid duplicates. Your cooperation is crucial in keeping our community's discussions constructive and organized.

  • Mandatory completion of issue templates: We need all of the information required in our issue templates because it ensures that every user and maintainer, regardless of their experience, can understand the content and severity of your bug report or change request.

  • Closing incomplete issues: We reserve the right to close issues lacking essential information, such as but not limited to [minimal reproductions] or those not adhering to the quality standards and requirements specified in our issue templates. Such issues can be reopened once the missing information has been provided.

  • Handling duplicates: To maintain organized and efficient communication within our [issue tracker] and discussion board, we reserve the right to close any duplicated issues or lock duplicated discussions. Opening multiple channels to ask the same question or report the same issue across different forums hinders our ability to manage and address community concerns effectively. This approach is vital for efficient time management, as duplicated questions can consume the time of multiple team members simultaneously. Ensuring that each issue or discussion is unique and progresses with new information helps us to maintain focus and support our community.

    We further reserve the right to immediately close discussions or issues that are reopened without providing new information or simply because users have not yet received a response to their issue/question, as the issue is marked as incomplete.

  • Limitations of automated tools: While we believe in the value and efficiency that automated tools bring to identifying potential issues (such as those identified by Lighthouse, Accessibility tools, and others), simply submitting an issue generated by these tools does not constitute a complete bug report. These tools sometimes produce verbose outputs and may include false positives, which necessitate a critical evaluation. You are of course welcome to attach generated reports to your issue. However, this does not substitute the requirement for a minimal reproduction or a thorough discussion of the findings. We reserve the right to mark these issues as incomplete and close them. This practice ensures that we are addressing genuine concerns with precision and clarity, rather than navigating through extensive automated outputs.


  1. Warning and blocking policy: Given the increasing popularity of our project and our commitment to a healthy community, we've defined clear guidelines on how we proceed with violations:

    1.1. First warning: Users displaying repeated inappropriate, offensive, or harmful behavior will receive a first warning. This warning serves as a formal notice that their behavior is not in alignment with our community standards and Code of Conduct. The first warning is permanent.

    1.2. Second warning and opportunity for resolution: If the behavior persists, a second warning will be issued. Upon receiving the second warning, the user will be given a 5-day period for reflection, during which they are encouraged to publicly explain or apologize for their actions. This period is designed to offer an opportunity for openly clearing out any misunderstanding.

    1.3. Blocking: Should there be no response or improvement in behavior following the second warning, we reserve the right to block the user from the community and repository. Blocking is considered a last resort, used only when absolutely necessary to protect the community's integrity and positive atmosphere.

    Blocking has been an exceptionally rare necessity in our overwhelmingly positive community, highlighting our preference for constructive dialogue and mutual respect. It aims to protect our community members and team. 

\ No newline at end of file diff --git a/main/community/index.html b/main/community/index.html index d2aab7729..dd505f6a5 100644 --- a/main/community/index.html +++ b/main/community/index.html @@ -1 +1 @@ - Community - Chainsaw
Skip to content

Community

Chainsaw has a growing community and we would definitely love to see you join and contribute.

Everyone is welcome to make suggestions, report bugs, open feature requests, contribute code or docs, participate in discussions, write blogs or anything that can benefit the project.


Chainsaw is built and maintained under the Kyverno umbrella but decisions are

Community driven

Everyone's voice matters


Slack channel

Join our slack channel #kyverno-chainsaw to meet with users, contributors and maintainers.

Community Meetings

To attend our community meetings, join the Chainsaw group. You will then be sent a meeting invite and will have access to the agenda and meeting notes. Any member may suggest topics for discussion.

This is a public, weekly for Kyverno-Chainsaw maintainers to make announcements and provide project updates, and request input and feedback. This forum allows community members to raise agenda items of any sort, including but not limited to any PRs or issues on which they are working.

Weekly every Thursday at 2:00 PM UTC

RoadMap

For detailed information on our planned features and upcoming updates, please view our Roadmap.

Contributing

Please read the contributing guide for details around:

  1. Code of Conduct
  2. Code Culture
  3. Details on how to contribute

Adopters

If you are using Chainsaw and want to share it publicly we always appreciate a bit of support. Pull requests to the ADOPTERS LIST will put a smile on our faces 😄

\ No newline at end of file + Community - Chainsaw
Skip to content

Community

Chainsaw has a growing community and we would definitely love to see you join and contribute.

Everyone is welcome to make suggestions, report bugs, open feature requests, contribute code or docs, participate in discussions, write blogs or anything that can benefit the project.


Chainsaw is built and maintained under the Kyverno umbrella but decisions are

Community driven

Everyone's voice matters


Slack channel

Join our slack channel #kyverno-chainsaw to meet with users, contributors and maintainers.

Community Meetings

To attend our community meetings, join the Chainsaw group. You will then be sent a meeting invite and will have access to the agenda and meeting notes. Any member may suggest topics for discussion.

This is a public, weekly for Kyverno-Chainsaw maintainers to make announcements and provide project updates, and request input and feedback. This forum allows community members to raise agenda items of any sort, including but not limited to any PRs or issues on which they are working.

Weekly every Thursday at 2:00 PM UTC

RoadMap

For detailed information on our planned features and upcoming updates, please view our Roadmap.

Contributing

Please read the contributing guide for details around:

  1. Code of Conduct
  2. Code Culture
  3. Details on how to contribute

Adopters

If you are using Chainsaw and want to share it publicly we always appreciate a bit of support. Pull requests to the ADOPTERS LIST will put a smile on our faces 😄

\ No newline at end of file diff --git a/main/community/making-a-pull-request/index.html b/main/community/making-a-pull-request/index.html index 6392f6c19..c7d188e77 100644 --- a/main/community/making-a-pull-request/index.html +++ b/main/community/making-a-pull-request/index.html @@ -1,4 +1,4 @@ - Making a pull request - Chainsaw
Skip to content

Pull Requests

You can contribute to Chainsaw by making a pull request that will be reviewed by maintainers and integrated into the main repository when the changes made are approved. You can contribute bug fixes, documentation changes, or new functionalities.

Considering a pull request

Before deciding to spend effort on making changes and creating a pull request, please discuss what you intend to do. If you are responding to what you think might be a bug, please issue a bug report first. If you intend to work on documentation, create a documentation issue. If you want to work on a new feature, please create a change request.

Keep in mind the guidance given and let people advise you. It might be that there are easier solutions to the problem you perceive and want to address. It might be that what you want to achieve can already be done by configuration or [customization].

Learning about pull requests

Pull requests are a concept layered on top of Git by services that provide Git hosting. Before you consider making a pull request, you should familiarize yourself with the documentation on GitHub, the service we are using. The following articles are of particular importance:

  1. Forking a repository
  2. Creating a pull request from a fork
  3. Creating a pull request

Note that they provide tailored documentation for different operating systems and different ways of interacting with GitHub. We do our best in the documentation here to describe the process as it applies to Chainsaw but cannot cover all possible combinations of tools and ways of doing things. It is also important that you understand the concept of a pull-request in general before continuing.

Pull request process

In the following, we describe the general process for making pull requests. The aim here is to provide the 30k ft overview before describing details later on.

Preparing changes and draft PR

The diagram below describes what typically happens to repositories in the process or preparing a pull request. We will be discussing the review-revise process below. It is important that you understand the overall process first before you worry about specific commands. This is why we cover this first before providing instructions below.

sequenceDiagram
+ Making a pull request - Chainsaw      

Pull Requests

You can contribute to Chainsaw by making a pull request that will be reviewed by maintainers and integrated into the main repository when the changes made are approved. You can contribute bug fixes, documentation changes, or new functionalities.

Considering a pull request

Before deciding to spend effort on making changes and creating a pull request, please discuss what you intend to do. If you are responding to what you think might be a bug, please issue a bug report first. If you intend to work on documentation, create a documentation issue. If you want to work on a new feature, please create a change request.

Keep in mind the guidance given and let people advise you. It might be that there are easier solutions to the problem you perceive and want to address. It might be that what you want to achieve can already be done by configuration or [customization].

Learning about pull requests

Pull requests are a concept layered on top of Git by services that provide Git hosting. Before you consider making a pull request, you should familiarize yourself with the documentation on GitHub, the service we are using. The following articles are of particular importance:

  1. Forking a repository
  2. Creating a pull request from a fork
  3. Creating a pull request

Note that they provide tailored documentation for different operating systems and different ways of interacting with GitHub. We do our best in the documentation here to describe the process as it applies to Chainsaw but cannot cover all possible combinations of tools and ways of doing things. It is also important that you understand the concept of a pull-request in general before continuing.

Pull request process

In the following, we describe the general process for making pull requests. The aim here is to provide the 30k ft overview before describing details later on.

Preparing changes and draft PR

The diagram below describes what typically happens to repositories in the process or preparing a pull request. We will be discussing the review-revise process below. It is important that you understand the overall process first before you worry about specific commands. This is why we cover this first before providing instructions below.

sequenceDiagram
   autonumber
 
   participant chainsaw
@@ -41,4 +41,4 @@
     local ->> local: delete branch
     fork ->> local: pull
   end
-
  1. Finalize PR: Signal that your changes are ready for review.
  2. Request Review: Ask the maintainer to review your changes.
  3. Discuss and Revise: Engage in discussions, make necessary revisions, and iterate.
  4. Merge and Squash: Once approved, the maintainer will merge and possibly squash your commits.
  5. Clean Up: Delete the branch used for the PR from both your fork and local clone.
\ No newline at end of file +
  1. Finalize PR: Signal that your changes are ready for review.
  2. Request Review: Ask the maintainer to review your changes.
  3. Discuss and Revise: Engage in discussions, make necessary revisions, and iterate.
  4. Merge and Squash: Once approved, the maintainer will merge and possibly squash your commits.
  5. Clean Up: Delete the branch used for the PR from both your fork and local clone.
\ No newline at end of file diff --git a/main/community/reporting-a-bug/index.html b/main/community/reporting-a-bug/index.html index d14f9173a..c774190d5 100644 --- a/main/community/reporting-a-bug/index.html +++ b/main/community/reporting-a-bug/index.html @@ -1,2 +1,2 @@ - Reporting a bug - Chainsaw
Skip to content

Bug Reports

Chainsaw, developed by Kyverno, is an actively maintained project that we constantly strive to improve. With a project of this size and complexity, bugs may occur. If you think you have discovered a bug, you can help us by submitting an issue in our public issue tracker, following this guide.

Before Creating an Issue

With numerous users, issues are created regularly. The maintainers of this project strive to address bugs promptly. By following this guide, you will know exactly what information we need to help you quickly.

Please do the following before creating an issue:

Upgrade to Latest Version

Chances are that the bug you discovered was already fixed in a subsequent version. Before reporting an issue, ensure that you're running the [latest version] of Chainsaw. Consult our [upgrade guide] to learn how to upgrade to the latest version.

Bug fixes are not backported

Please understand that only bugs that occur in the latest version of Chainsaw will be addressed. Also, to reduce duplicate efforts, fixes cannot be backported to earlier versions.

Remove Customizations

If you're using customizations like additional configurations, remove them before reporting a bug. We can't offer official support for bugs that might hide in your overrides, so make sure to omit custom settings from your configuration files.

Don't be shy to ask on our discussion board for help if you run into problems.

Search for Solutions

At this stage, we know that the problem persists in the latest version and is not caused by any of your customizations. However, the problem might result from a small typo or a syntactical error in a configuration file.

Before creating a bug report, save time for us and yourself by doing some research:

  1. Search our documentation for relevant sections related to your problem. Ensure everything is configured correctly.
  2. [Search our issue tracker] as another user might have already reported the same problem.
  3. [Search our discussion board] to see if other users are facing similar issues and find possible solutions.

Keep track of all search terms and relevant links; you'll need them in the bug report.


If you still haven't found a solution to your problem, create an issue. It's now likely that you've encountered something new. Read the following section to learn how to create a complete and helpful bug report.

Issue Template

We have created a new issue template to make the bug reporting process as simple as possible and more efficient for our community and us. It consists of the following parts:

Title

A good title is short and descriptive. It should be a one-sentence executive summary of the issue, so the impact and severity of the bug can be inferred from the title.

Example
Clear Chainsaw apply command fails with specific CRD
Wordy The apply command in Chainsaw fails when used with a certain Custom Resource Definition
Unclear Command does not work
Useless Help

Context optional

Before describing the bug, you can provide additional context to help us understand what you were trying to achieve. Explain the circumstances under which you're using Chainsaw, and what you think might be relevant. Don't describe the bug here.

Bug Description

Provide a clear, focused, specific, and concise summary of the bug you encountered. Explain why you think this is a bug that should be reported to Chainsaw, and not to one of its dependencies. Follow these principles:

  • Explain the what, not the how – don't explain how to reproduce the bug here, we're getting there. Focus on articulating the problem and its impact.
  • Keep it short and concise – if the bug can be precisely explained in one or two sentences, perfect. Don't inflate it.
  • One bug at a time – if you encounter several unrelated bugs, create separate issues for them.

Share links to relevant sections of our documentation and any related issues or discussions. This helps us improve our documentation and understand the problem better.

Reproduction

A minimal reproduction is essential for a well-written bug report, as it allows us to recreate the conditions necessary to inspect the bug. Follow the guide to create a reproduction:

[ Create reproduction][Create reproduction]{ .md-button .md-button--primary }

After creating the reproduction, you should have a .zip file, ideally not larger than 1 MB. Drag and drop the .zip file into the issue field, which will automatically upload it to GitHub.

Don't share links to repositories

While linking to a repository is a common practice, we currently don't support this. The reproduction, created using the built-in info plugin, contains all necessary environment information.

Steps to Reproduce

List specific steps to follow when running your reproduction to observe the bug. Keep the steps concise and ensure nothing is left out. Use simple language and focus on continuity.

Browser optional

If the bug only occurs in specific browsers, let us know which ones are affected. This field is optional, as it is only relevant for bugs that do not involve a crash when previewing or building your site.

Incognito Mode

Verify that the bug is not caused by a browser extension by switching to incognito mode. If the bug disappears, it is likely caused by an extension.

Checklist

Before submitting, ensure you have:

  • Followed this guide thoroughly
  • Provided all necessary information
  • Created a minimal reproduction

Thanks for following the guide and creating a high-quality bug report. We will take it from here.

\ No newline at end of file + Reporting a bug - Chainsaw
Skip to content

Bug Reports

Chainsaw, developed by Kyverno, is an actively maintained project that we constantly strive to improve. With a project of this size and complexity, bugs may occur. If you think you have discovered a bug, you can help us by submitting an issue in our public issue tracker, following this guide.

Before Creating an Issue

With numerous users, issues are created regularly. The maintainers of this project strive to address bugs promptly. By following this guide, you will know exactly what information we need to help you quickly.

Please do the following before creating an issue:

Upgrade to Latest Version

Chances are that the bug you discovered was already fixed in a subsequent version. Before reporting an issue, ensure that you're running the [latest version] of Chainsaw. Consult our [upgrade guide] to learn how to upgrade to the latest version.

Bug fixes are not backported

Please understand that only bugs that occur in the latest version of Chainsaw will be addressed. Also, to reduce duplicate efforts, fixes cannot be backported to earlier versions.

Remove Customizations

If you're using customizations like additional configurations, remove them before reporting a bug. We can't offer official support for bugs that might hide in your overrides, so make sure to omit custom settings from your configuration files.

Don't be shy to ask on our discussion board for help if you run into problems.

Search for Solutions

At this stage, we know that the problem persists in the latest version and is not caused by any of your customizations. However, the problem might result from a small typo or a syntactical error in a configuration file.

Before creating a bug report, save time for us and yourself by doing some research:

  1. Search our documentation for relevant sections related to your problem. Ensure everything is configured correctly.
  2. [Search our issue tracker] as another user might have already reported the same problem.
  3. [Search our discussion board] to see if other users are facing similar issues and find possible solutions.

Keep track of all search terms and relevant links; you'll need them in the bug report.


If you still haven't found a solution to your problem, create an issue. It's now likely that you've encountered something new. Read the following section to learn how to create a complete and helpful bug report.

Issue Template

We have created a new issue template to make the bug reporting process as simple as possible and more efficient for our community and us. It consists of the following parts:

Title

A good title is short and descriptive. It should be a one-sentence executive summary of the issue, so the impact and severity of the bug can be inferred from the title.

Example
Clear Chainsaw apply command fails with specific CRD
Wordy The apply command in Chainsaw fails when used with a certain Custom Resource Definition
Unclear Command does not work
Useless Help

Context optional

Before describing the bug, you can provide additional context to help us understand what you were trying to achieve. Explain the circumstances under which you're using Chainsaw, and what you think might be relevant. Don't describe the bug here.

Bug Description

Provide a clear, focused, specific, and concise summary of the bug you encountered. Explain why you think this is a bug that should be reported to Chainsaw, and not to one of its dependencies. Follow these principles:

  • Explain the what, not the how – don't explain how to reproduce the bug here, we're getting there. Focus on articulating the problem and its impact.
  • Keep it short and concise – if the bug can be precisely explained in one or two sentences, perfect. Don't inflate it.
  • One bug at a time – if you encounter several unrelated bugs, create separate issues for them.

Share links to relevant sections of our documentation and any related issues or discussions. This helps us improve our documentation and understand the problem better.

Reproduction

A minimal reproduction is essential for a well-written bug report, as it allows us to recreate the conditions necessary to inspect the bug. Follow the guide to create a reproduction:

[ Create reproduction][Create reproduction]{ .md-button .md-button--primary }

After creating the reproduction, you should have a .zip file, ideally not larger than 1 MB. Drag and drop the .zip file into the issue field, which will automatically upload it to GitHub.

Don't share links to repositories

While linking to a repository is a common practice, we currently don't support this. The reproduction, created using the built-in info plugin, contains all necessary environment information.

Steps to Reproduce

List specific steps to follow when running your reproduction to observe the bug. Keep the steps concise and ensure nothing is left out. Use simple language and focus on continuity.

Browser optional

If the bug only occurs in specific browsers, let us know which ones are affected. This field is optional, as it is only relevant for bugs that do not involve a crash when previewing or building your site.

Incognito Mode

Verify that the bug is not caused by a browser extension by switching to incognito mode. If the bug disappears, it is likely caused by an extension.

Checklist

Before submitting, ensure you have:

  • Followed this guide thoroughly
  • Provided all necessary information
  • Created a minimal reproduction

Thanks for following the guide and creating a high-quality bug report. We will take it from here.

\ No newline at end of file diff --git a/main/community/reporting-a-docs-issue/index.html b/main/community/reporting-a-docs-issue/index.html index c59e6a8a0..187c5b322 100644 --- a/main/community/reporting-a-docs-issue/index.html +++ b/main/community/reporting-a-docs-issue/index.html @@ -1 +1 @@ - Reporting a docs issue - Chainsaw
Skip to content

Documentation Issues

The Chainsaw documentation includes extensive information on features, configurations, customizations, and more. If you have found an inconsistency or see room for improvement, please follow this guide to submit an issue on our issue tracker.

Issue Template

Reporting a documentation issue is usually less involved than reporting a bug, as we don't need a [reproduction]. Please thoroughly read this guide before creating a new documentation issue, and provide the following information as part of the issue:

Title

A good title should be a short, one-sentence description of the issue, containing all relevant information and keywords to simplify the search in our issue tracker.

Example
Clear Clarify resource templating setup in Chainsaw
Unclear Missing information in the docs
Useless Help

Description

Provide a clear and concise summary of the inconsistency or issue you encountered in the documentation or the documentation section that needs improvement. Explain why you think the documentation should be adjusted and describe the severity of the issue:

  • Keep it short and concise – if the inconsistency or issue can be precisely explained in one or two sentences, perfect. Maintainers and future users will be grateful for having to read less.
  • One issue at a time – if you encounter several unrelated inconsistencies, please create separate issues for them.

Why we need this: describing the problem clearly and concisely is a prerequisite for improving our documentation – we need to understand what's wrong so we can fix it.

After you describe the documentation section that needs to be adjusted, share the link to this specific documentation section and other possibly related sections. Use anchor links (permanent links) where possible, as it simplifies discovery.

Why we need this: providing the links to the documentation helps us understand which sections of our documentation need to be adjusted, extended, or overhauled.

Proposed Change optional

Now that you have provided us with the description and links to the documentation sections, you can help us, maintainers, and the community by proposing an improvement. You can sketch out rough ideas or write a concrete proposal. This field is optional but very helpful.

Why we need this: an improvement proposal can be beneficial for other users who encounter the same issue, as they offer solutions before we maintainers can update the documentation.

Checklist

Thanks for following the guide and providing valuable feedback for our documentation – you are almost done. The checklist ensures that you have read this guide and have worked to your best knowledge to provide us with every piece of information we need to improve it.

We'll take it from here.

\ No newline at end of file + Reporting a docs issue - Chainsaw
Skip to content

Documentation Issues

The Chainsaw documentation includes extensive information on features, configurations, customizations, and more. If you have found an inconsistency or see room for improvement, please follow this guide to submit an issue on our issue tracker.

Issue Template

Reporting a documentation issue is usually less involved than reporting a bug, as we don't need a [reproduction]. Please thoroughly read this guide before creating a new documentation issue, and provide the following information as part of the issue:

Title

A good title should be a short, one-sentence description of the issue, containing all relevant information and keywords to simplify the search in our issue tracker.

Example
Clear Clarify resource templating setup in Chainsaw
Unclear Missing information in the docs
Useless Help

Description

Provide a clear and concise summary of the inconsistency or issue you encountered in the documentation or the documentation section that needs improvement. Explain why you think the documentation should be adjusted and describe the severity of the issue:

  • Keep it short and concise – if the inconsistency or issue can be precisely explained in one or two sentences, perfect. Maintainers and future users will be grateful for having to read less.
  • One issue at a time – if you encounter several unrelated inconsistencies, please create separate issues for them.

Why we need this: describing the problem clearly and concisely is a prerequisite for improving our documentation – we need to understand what's wrong so we can fix it.

After you describe the documentation section that needs to be adjusted, share the link to this specific documentation section and other possibly related sections. Use anchor links (permanent links) where possible, as it simplifies discovery.

Why we need this: providing the links to the documentation helps us understand which sections of our documentation need to be adjusted, extended, or overhauled.

Proposed Change optional

Now that you have provided us with the description and links to the documentation sections, you can help us, maintainers, and the community by proposing an improvement. You can sketch out rough ideas or write a concrete proposal. This field is optional but very helpful.

Why we need this: an improvement proposal can be beneficial for other users who encounter the same issue, as they offer solutions before we maintainers can update the documentation.

Checklist

Thanks for following the guide and providing valuable feedback for our documentation – you are almost done. The checklist ensures that you have read this guide and have worked to your best knowledge to provide us with every piece of information we need to improve it.

We'll take it from here.

\ No newline at end of file diff --git a/main/community/requesting-a-change/index.html b/main/community/requesting-a-change/index.html index 32c8e0572..8e45d53bb 100644 --- a/main/community/requesting-a-change/index.html +++ b/main/community/requesting-a-change/index.html @@ -1 +1 @@ - Requesting a change - Chainsaw
Skip to content

Change Requests

Chainsaw by Kyverno is a powerful tool for end-to-end testing. Serving a wide range of use cases, we value every idea or contribution from our community. Please follow this guide before submitting your change request in our public issue tracker. This helps us better understand the proposed change and how it will benefit our community.

Before Creating an Issue

Before you invest time in submitting a change request, answer these questions to determine if your idea is a good fit for Chainsaw and matches the project's philosophy and tone.

It's Not a Bug, It's a Feature

Change requests suggest minor adjustments, new features, or influence the project's direction. They are not intended for reporting bugs. Refer to our bug reporting guide for that.

Look for Sources of Inspiration

If your idea is implemented in another tool or framework, collect information on its implementation. This helps us evaluate its fit more quickly.

Connect with Our Community

Our discussion board is the best place to connect with our community. Seeking input from other users helps implement features that benefit a larger number of users.

Start a discussion

Issue Template

After doing the preliminary work, create a change request. Follow these steps:

Title

A good title is short and descriptive, summarizing the idea so the potential impact and benefit can be inferred.

Example
Clear Support for resource templating in Chainsaw
Wordy Add support for templating resources in Chainsaw for easier testing
Unclear Improve templating
Useless Help

Context optional

Provide additional context to help us understand what you are trying to achieve. Explain the circumstances and relevant settings without describing the change request itself.

Description

Provide a detailed and clear description of your idea. Explain why your idea is relevant to Chainsaw and should be implemented here, not in one of its dependencies.

  • Explain the what, not the why – focus on describing the change request precisely.
  • Keep it short and concise – be brief and to the point.
  • One idea at a time – if you have multiple ideas, open separate change requests for each.

Provide any relevant links to issues, discussions, or documentation sections related to your change request. This helps us gain additional context.

Use Cases

Explain how your change request would work from an author's and user's perspective. What is the expected impact, and why does it benefit other users? Would it potentially break existing functionality?

Visuals optional

If you have any visuals, such as sketches, screenshots, mockups, or external assets, present them in this section. If you have seen this change used in other tools, showcase and describe its implementation.

Checklist

Thanks for following the guide and creating a high-quality change request. The checklist ensures that you have read this guide and provided all necessary information for us to review your idea.

We'll take it from here.

Rejected Requests

Your change request got rejected? We're sorry for that. We understand it can be frustrating, but we always need to consider the needs of our entire community. If you're unsure why your change request was rejected, please ask for clarification.

We consider the following principles when evaluating change requests:

  • Alignment with the project's vision and tone
  • Compatibility with existing features and plugins
  • Compatibility with all screen sizes and browsers
  • Effort of implementation and maintenance
  • Usefulness to the majority of users
  • Simplicity and ease of use
  • Accessibility

If your idea was rejected, you can always implement it via [customization]. If you're unsure how or want to know if someone has already done it, get in touch with our community on the discussion board.

\ No newline at end of file + Requesting a change - Chainsaw
Skip to content

Change Requests

Chainsaw by Kyverno is a powerful tool for end-to-end testing. Serving a wide range of use cases, we value every idea or contribution from our community. Please follow this guide before submitting your change request in our public issue tracker. This helps us better understand the proposed change and how it will benefit our community.

Before Creating an Issue

Before you invest time in submitting a change request, answer these questions to determine if your idea is a good fit for Chainsaw and matches the project's philosophy and tone.

It's Not a Bug, It's a Feature

Change requests suggest minor adjustments, new features, or influence the project's direction. They are not intended for reporting bugs. Refer to our bug reporting guide for that.

Look for Sources of Inspiration

If your idea is implemented in another tool or framework, collect information on its implementation. This helps us evaluate its fit more quickly.

Connect with Our Community

Our discussion board is the best place to connect with our community. Seeking input from other users helps implement features that benefit a larger number of users.

Start a discussion

Issue Template

After doing the preliminary work, create a change request. Follow these steps:

Title

A good title is short and descriptive, summarizing the idea so the potential impact and benefit can be inferred.

Example
Clear Support for resource templating in Chainsaw
Wordy Add support for templating resources in Chainsaw for easier testing
Unclear Improve templating
Useless Help

Context optional

Provide additional context to help us understand what you are trying to achieve. Explain the circumstances and relevant settings without describing the change request itself.

Description

Provide a detailed and clear description of your idea. Explain why your idea is relevant to Chainsaw and should be implemented here, not in one of its dependencies.

  • Explain the what, not the why – focus on describing the change request precisely.
  • Keep it short and concise – be brief and to the point.
  • One idea at a time – if you have multiple ideas, open separate change requests for each.

Provide any relevant links to issues, discussions, or documentation sections related to your change request. This helps us gain additional context.

Use Cases

Explain how your change request would work from an author's and user's perspective. What is the expected impact, and why does it benefit other users? Would it potentially break existing functionality?

Visuals optional

If you have any visuals, such as sketches, screenshots, mockups, or external assets, present them in this section. If you have seen this change used in other tools, showcase and describe its implementation.

Checklist

Thanks for following the guide and creating a high-quality change request. The checklist ensures that you have read this guide and provided all necessary information for us to review your idea.

We'll take it from here.

Rejected Requests

Your change request got rejected? We're sorry for that. We understand it can be frustrating, but we always need to consider the needs of our entire community. If you're unsure why your change request was rejected, please ask for clarification.

We consider the following principles when evaluating change requests:

  • Alignment with the project's vision and tone
  • Compatibility with existing features and plugins
  • Compatibility with all screen sizes and browsers
  • Effort of implementation and maintenance
  • Usefulness to the majority of users
  • Simplicity and ease of use
  • Accessibility

If your idea was rejected, you can always implement it via [customization]. If you're unsure how or want to know if someone has already done it, get in touch with our community on the discussion board.

\ No newline at end of file diff --git a/main/configuration/file/index.html b/main/configuration/file/index.html index 2567fea00..2ebdbdb47 100644 --- a/main/configuration/file/index.html +++ b/main/configuration/file/index.html @@ -1,4 +1,4 @@ - Configuration file - Chainsaw
Skip to content

Configuration file

Chainsaw prioritizes its configuration in the following order:

  1. User-specified configuration

    If you explicitly provide a configuration file using a command-line flag

  2. Default configuration file

    If no configuration is specified, Chainsaw will look for a default file named .chainsaw.yaml in the current working directory

  3. Internal default configuration

    In the absence of both of the above, Chainsaw will use a default configuration file embedded in the Chainsaw binary

Example

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Configuration file - Chainsaw      

Configuration file

Chainsaw prioritizes its configuration in the following order:

  1. User-specified configuration

    If you explicitly provide a configuration file using a command-line flag

  2. Default configuration file

    If no configuration is specified, Chainsaw will look for a default file named .chainsaw.yaml in the current working directory

  3. Internal default configuration

    In the absence of both of the above, Chainsaw will use a default configuration file embedded in the Chainsaw binary

Example

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -22,4 +22,4 @@
 metadata:
   name: default
 spec: {}
-

Reference documentation

See Configuration API reference for more details.

\ No newline at end of file +

Reference documentation

See Configuration API reference for more details.

\ No newline at end of file diff --git a/main/configuration/flags/index.html b/main/configuration/flags/index.html index 36f2a5422..5f19320d4 100644 --- a/main/configuration/flags/index.html +++ b/main/configuration/flags/index.html @@ -1,4 +1,4 @@ - Command line flags - Chainsaw
Skip to content

Command line flags

After a configuration file is loaded, you can override specific settings using command-line flags.

Precedence

Command-line flags always take precedence over the configuration coming from a configuration file.

Example

chainsaw test                         \
+ Command line flags - Chainsaw      

Command line flags

After a configuration file is loaded, you can override specific settings using command-line flags.

Precedence

Command-line flags always take precedence over the configuration coming from a configuration file.

Example

chainsaw test                         \
   path/to/test/dir                    \
   --config path/to/your/config.yaml   \
   --assert-timeout 45s                \
@@ -6,4 +6,4 @@
   --fail-fast true                    \
   --parallel 4                        \
   ...
-

In this example, Chainsaw will load a configuration file but the timeout configuration and other settings will be overridden by the values set in the flags, regardless of the value in the loaded configuration file.

Reference documentation

See chainsaw test command reference for the list of all available flags.

\ No newline at end of file +

In this example, Chainsaw will load a configuration file but the timeout configuration and other settings will be overridden by the values set in the flags, regardless of the value in the loaded configuration file.

Reference documentation

See chainsaw test command reference for the list of all available flags.

\ No newline at end of file diff --git a/main/configuration/index.html b/main/configuration/index.html index 65a16c9de..b8f5e56fc 100644 --- a/main/configuration/index.html +++ b/main/configuration/index.html @@ -1 +1 @@ - Configuring Chainsaw - Chainsaw
Skip to content

Configuring Chainsaw

This documentation focuses on providing a breakdown of the Chainsaw configuration structure and how to use it.

Chainsaw can be configured in two different and complementary ways:

Specific configuration options

Please pay attention to the configuration options below, they may or may not be relevant in your case but can be useful in certain cases:

\ No newline at end of file + Configuring Chainsaw - Chainsaw
Skip to content

Configuring Chainsaw

This documentation focuses on providing a breakdown of the Chainsaw configuration structure and how to use it.

Chainsaw can be configured in two different and complementary ways:

Specific configuration options

Please pay attention to the configuration options below, they may or may not be relevant in your case but can be useful in certain cases:

\ No newline at end of file diff --git a/main/configuration/options/cleanup/index.html b/main/configuration/options/cleanup/index.html index 63214b3c7..c4153306a 100644 --- a/main/configuration/options/cleanup/index.html +++ b/main/configuration/options/cleanup/index.html @@ -1,4 +1,4 @@ - Cleanup options - Chainsaw
Skip to content

Cleanup options

Cleanup options contain the configuration used by Chainsaw for cleaning up resources.

Supported elements

Element Default Description
skipDelete false If set, do not delete the resources after running a test.
delayBeforeCleanup DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.

Delay before cleanup

At the end of each test, Chainsaw will delete the resources it created during the test.

When testing operators, it can be useful to wait a little bit before starting the cleanup process to make sure the operator/controller has the necessary time to update its internal state.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Cleanup options - Chainsaw      

Cleanup options

Cleanup options contain the configuration used by Chainsaw for cleaning up resources.

Supported elements

Element Default Description
skipDelete false If set, do not delete the resources after running a test.
delayBeforeCleanup DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.

Delay before cleanup

At the end of each test, Chainsaw will delete the resources it created during the test.

When testing operators, it can be useful to wait a little bit before starting the cleanup process to make sure the operator/controller has the necessary time to update its internal state.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -9,4 +9,4 @@
 

With flags

chainsaw test                   \
   --skip-delete                 \
   --cleanup-delay 5s
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/configuration/options/clusters/index.html b/main/configuration/options/clusters/index.html index 680d359db..6aea55bc5 100644 --- a/main/configuration/options/clusters/index.html +++ b/main/configuration/options/clusters/index.html @@ -1,4 +1,4 @@ - Multi-cluster options - Chainsaw
Skip to content

Multi-cluster options

Multi-cluster options contain the configuration of additional clusters.

Supported elements

Every cluster is registered by name and supports the following elements:

Element Default Description
kubeconfig string Kubeconfig is the path to the referenced file.
context string Context is the name of the context to use.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Multi-cluster options - Chainsaw      

Multi-cluster options

Multi-cluster options contain the configuration of additional clusters.

Supported elements

Every cluster is registered by name and supports the following elements:

Element Default Description
kubeconfig string Kubeconfig is the path to the referenced file.
context string Context is the name of the context to use.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: custom-config
@@ -16,4 +16,4 @@
 

With flags

Note

The --cluster flag can appear multiple times and is expected to come in the following format:

--cluster cluster-name=/path/to/kubeconfig[:context-name].

chainsaw test                                               \
     --cluster cluster-1=/path/to/kubeconfig-1               \
     --cluster cluster-2=/path/to/kubeconfig-2:context-2
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/configuration/options/deletion/index.html b/main/configuration/options/deletion/index.html index 48e7207a4..6d6758244 100644 --- a/main/configuration/options/deletion/index.html +++ b/main/configuration/options/deletion/index.html @@ -1,4 +1,4 @@ - Deletion options - Chainsaw
Skip to content

Deletion options

Deletion options determine the configuration used by Chainsaw for deleting resources.

Supported elements

Element Default Description
propagation Background Propagation decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation.

Propagation

This element will affect Kubernetes cascading deletion. Supported values are Orphan, Background and Foreground.

Tip

Setting Orphan is probably never a good idea because it would leak resources in the test cluster. Chainsaw uses Background as its default value which is a reasonable choice.

Note that Foreground can be useful to fail when the dependent resources fail to delete.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Deletion options - Chainsaw      

Deletion options

Deletion options determine the configuration used by Chainsaw for deleting resources.

Supported elements

Element Default Description
propagation Background Propagation decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation.

Propagation

This element will affect Kubernetes cascading deletion. Supported values are Orphan, Background and Foreground.

Tip

Setting Orphan is probably never a good idea because it would leak resources in the test cluster. Chainsaw uses Background as its default value which is a reasonable choice.

Note that Foreground can be useful to fail when the dependent resources fail to delete.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -6,4 +6,4 @@
   deletion:
     propagation: Foreground
 

With flags

chainsaw test --deletion-propagation-policy Foreground
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/configuration/options/discovery/index.html b/main/configuration/options/discovery/index.html index 2f7801b86..55ff60f3c 100644 --- a/main/configuration/options/discovery/index.html +++ b/main/configuration/options/discovery/index.html @@ -1,4 +1,4 @@ - Discovery options - Chainsaw
Skip to content

Discovery options

Discovery options contain the discovery configuration used by Chainsaw when discovering tests in specified folders.

Supported elements

Element Default Description
testFile chainsaw-test TestFile is the name of the file containing the test to run. If no extension is provided, chainsaw will try with .yaml first and .yml if needed.
fullName false FullName makes use of the full test case folder path instead of the folder name.
includeTestRegex IncludeTestRegex is used to include tests based on a regular expression.
excludeTestRegex ExcludeTestRegex is used to exclude tests based on a regular expression.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Discovery options - Chainsaw      

Discovery options

Discovery options contain the discovery configuration used by Chainsaw when discovering tests in specified folders.

Supported elements

Element Default Description
testFile chainsaw-test TestFile is the name of the file containing the test to run. If no extension is provided, chainsaw will try with .yaml first and .yml if needed.
fullName false FullName makes use of the full test case folder path instead of the folder name.
includeTestRegex IncludeTestRegex is used to include tests based on a regular expression.
excludeTestRegex ExcludeTestRegex is used to exclude tests based on a regular expression.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -13,4 +13,4 @@
   --full-name                                   \
   --include-test-regex 'chainsaw/.*'            \
   --exclude-test-regex 'chainsaw/exclude-.*'
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/configuration/options/error/index.html b/main/configuration/options/error/index.html index a6a24c615..107da9abc 100644 --- a/main/configuration/options/error/index.html +++ b/main/configuration/options/error/index.html @@ -1,4 +1,4 @@ - Error options - Chainsaw
Skip to content

Error options

Error options contain the global error configuration used by Chainsaw.

Supported elements

Field Default Description
catch Catch defines what the tests steps will execute when an error happens. This will be combined with catch handlers defined at the test and step levels.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Error options - Chainsaw      

Error options

Error options contain the global error configuration used by Chainsaw.

Supported elements

Field Default Description
catch Catch defines what the tests steps will execute when an error happens. This will be combined with catch handlers defined at the test and step levels.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -8,4 +8,4 @@
     - events: {}
     - describe:
         resource: crds
-

With flags

Note

Error options can't be configured with flags.

\ No newline at end of file +

With flags

Note

Error options can't be configured with flags.

\ No newline at end of file diff --git a/main/configuration/options/execution/index.html b/main/configuration/options/execution/index.html index d286da74a..adbcd5541 100644 --- a/main/configuration/options/execution/index.html +++ b/main/configuration/options/execution/index.html @@ -1,4 +1,4 @@ - Execution options - Chainsaw
Skip to content

Execution options

Execution options determine how tests are run by Chainsaw.

Supported elements

Element Default Description
failFast false FailFast determines whether the test should stop upon encountering the first failure.
parallel auto The maximum number of tests to run at once.
repeatCount 1 RepeatCount indicates how many times the tests should be executed.
forceTerminationGracePeriod ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.

Termination grace period

Some Kubernetes resources can take time before being terminated. For example, deleting a pod can take time if the underlying container doesn't quit quickly enough.

Chainsaw can override the grace period for the following resource kinds:

  • Pod
  • Deployment
  • StatefulSet
  • DaemonSet
  • Job
  • CronJob

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Execution options - Chainsaw      

Execution options

Execution options determine how tests are run by Chainsaw.

Supported elements

Element Default Description
failFast false FailFast determines whether the test should stop upon encountering the first failure.
parallel auto The maximum number of tests to run at once.
repeatCount 1 RepeatCount indicates how many times the tests should be executed.
forceTerminationGracePeriod ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.

Termination grace period

Some Kubernetes resources can take time before being terminated. For example, deleting a pod can take time if the underlying container doesn't quit quickly enough.

Chainsaw can override the grace period for the following resource kinds:

  • Pod
  • Deployment
  • StatefulSet
  • DaemonSet
  • Job
  • CronJob

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -13,4 +13,4 @@
   --parallel 8                                  \
   --repeat-count 2                              \
   --force-termination-grace-period 5s
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/configuration/options/label-selectors/index.html b/main/configuration/options/label-selectors/index.html index fdad5c971..483b999f2 100644 --- a/main/configuration/options/label-selectors/index.html +++ b/main/configuration/options/label-selectors/index.html @@ -1,2 +1,2 @@ - Label selectors - Chainsaw
Skip to content

Label selectors

Chainsaw can filter the tests to run using label selectors.

Configuration

With file

Note

Label selectors can't be configured with a configuration file.

With flags

chainsaw test --selector foo=bar
-
\ No newline at end of file + Label selectors - Chainsaw
Skip to content

Label selectors

Chainsaw can filter the tests to run using label selectors.

Configuration

With file

Note

Label selectors can't be configured with a configuration file.

With flags

chainsaw test --selector foo=bar
+
\ No newline at end of file diff --git a/main/configuration/options/namespace/index.html b/main/configuration/options/namespace/index.html index 1211da107..89597852e 100644 --- a/main/configuration/options/namespace/index.html +++ b/main/configuration/options/namespace/index.html @@ -1,4 +1,4 @@ - Namespace options - Chainsaw
Skip to content

Namespace options

Namespace options contain the configuration used by Chainsaw to allocate a namespace for each test.

Supported elements

Element Default Description
name Name defines the namespace to use for tests. If not specified, every test will execute in a random ephemeral namespace unless the namespace is overridden in a the test spec.
template Template defines a template to create the test namespace.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Namespace options - Chainsaw      

Namespace options

Namespace options contain the configuration used by Chainsaw to allocate a namespace for each test.

Supported elements

Element Default Description
name Name defines the namespace to use for tests. If not specified, every test will execute in a random ephemeral namespace unless the namespace is overridden in a the test spec.
template Template defines a template to create the test namespace.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -10,4 +10,4 @@
         annotations:
           from-config-file: hello
 

With flags

Note

The template element can't be configured with flags.

chainsaw test --namespace foo
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/configuration/options/no-cluster/index.html b/main/configuration/options/no-cluster/index.html index 8c50bc2d2..41610e6a9 100644 --- a/main/configuration/options/no-cluster/index.html +++ b/main/configuration/options/no-cluster/index.html @@ -1,2 +1,2 @@ - No cluster options - Chainsaw
Skip to content

No cluster options

Chainsaw can be run without any connection to a Kubernetes cluster.

In this case, Chainsaw will not try to create an ephemeral namespace and all operations requiring a Kubernetes cluster will fail.

Configuration

With file

Note

No cluster options can't be configured with a configuration file.

With flags

chainsaw test --no-cluster
-
\ No newline at end of file + No cluster options - Chainsaw
Skip to content

No cluster options

Chainsaw can be run without any connection to a Kubernetes cluster.

In this case, Chainsaw will not try to create an ephemeral namespace and all operations requiring a Kubernetes cluster will fail.

Configuration

With file

Note

No cluster options can't be configured with a configuration file.

With flags

chainsaw test --no-cluster
+
\ No newline at end of file diff --git a/main/configuration/options/pause/index.html b/main/configuration/options/pause/index.html index b4094c326..2be4f7866 100644 --- a/main/configuration/options/pause/index.html +++ b/main/configuration/options/pause/index.html @@ -1,2 +1,2 @@ - Pause options - Chainsaw
Skip to content

Pause options

Chainsaw can be configured to pause and wait for user input when a failure happens. This is useful when Chainsaw is run locally to allow debugging and troubleshooting failures.

Configuration

With file

Note

Pause options can't be configured with a configuration file.

With flags

chainsaw test --pause-on-failure
-
\ No newline at end of file + Pause options - Chainsaw
Skip to content

Pause options

Chainsaw can be configured to pause and wait for user input when a failure happens. This is useful when Chainsaw is run locally to allow debugging and troubleshooting failures.

Configuration

With file

Note

Pause options can't be configured with a configuration file.

With flags

chainsaw test --pause-on-failure
+
\ No newline at end of file diff --git a/main/configuration/options/report/index.html b/main/configuration/options/report/index.html index 8b7b251ef..be6b0944c 100644 --- a/main/configuration/options/report/index.html +++ b/main/configuration/options/report/index.html @@ -1,4 +1,4 @@ - Reporting options - Chainsaw
Skip to content

Reporting options

Reporting options contain the configuration used by Chainsaw for reporting.

Supported elements

Element Default Description
format JSON ReportFormat determines test report format (JSON
path ReportPath defines the path.
name chainsaw-report ReportName defines the name of report to create. It defaults to "chainsaw-report".

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Reporting options - Chainsaw      

Reporting options

Reporting options contain the configuration used by Chainsaw for reporting.

Supported elements

Element Default Description
format JSON ReportFormat determines test report format (JSON
path ReportPath defines the path.
name chainsaw-report ReportName defines the name of report to create. It defaults to "chainsaw-report".

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -11,4 +11,4 @@
   --report-format JSON                    \
   --report-name chainsaw-report           \
   --report-path /path/to/save/report
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/configuration/options/templating/index.html b/main/configuration/options/templating/index.html index 63ac873f4..eecb2d359 100644 --- a/main/configuration/options/templating/index.html +++ b/main/configuration/options/templating/index.html @@ -1,4 +1,4 @@ - Templating options - Chainsaw
Skip to content

Templating options

Templating options contain the templating configuration.

Supported elements

Element Default Description
enabled true Enabled determines whether resources should be considered for templating.

Tip

Templating was disabled by default in v0.1.* but is now enabled by default since v0.2.1.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Templating options - Chainsaw      

Templating options

Templating options contain the templating configuration.

Supported elements

Element Default Description
enabled true Enabled determines whether resources should be considered for templating.

Tip

Templating was disabled by default in v0.1.* but is now enabled by default since v0.2.1.

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -6,4 +6,4 @@
   templating:
     enabled: false
 

With flags

chainsaw test --template=false
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/configuration/options/timeouts/index.html b/main/configuration/options/timeouts/index.html index 3287fc0b0..90cd32015 100644 --- a/main/configuration/options/timeouts/index.html +++ b/main/configuration/options/timeouts/index.html @@ -1,4 +1,4 @@ - Timeouts - Chainsaw
Skip to content

Timeouts

Timeouts in Chainsaw are specified per type of operation. This is required because the timeout varies greatly depending on the nature of an operation.

For example, applying a manifest in a cluster is expected to execute reasonably fast, while validating a resource can be a much longer operation.

Supported timeouts

Element Default Description
apply 5s Used when Chainsaw applies manifests in a cluster
assert 30s Used when Chainsaw validates resources in a cluster
cleanup 30s Used when Chainsaw removes resources created for a test
delete 15s Used when Chainsaw deletes resources from a cluster
error 30s Used when Chainsaw validates resources in a cluster
exec 5s Used when Chainsaw executes arbitrary commands or scripts

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
+ Timeouts - Chainsaw      

Timeouts

Timeouts in Chainsaw are specified per type of operation. This is required because the timeout varies greatly depending on the nature of an operation.

For example, applying a manifest in a cluster is expected to execute reasonably fast, while validating a resource can be a much longer operation.

Supported timeouts

Element Default Description
apply 5s Used when Chainsaw applies manifests in a cluster
assert 30s Used when Chainsaw validates resources in a cluster
cleanup 30s Used when Chainsaw removes resources created for a test
delete 15s Used when Chainsaw deletes resources from a cluster
error 30s Used when Chainsaw validates resources in a cluster
exec 5s Used when Chainsaw executes arbitrary commands or scripts

Configuration

With file

apiVersion: chainsaw.kyverno.io/v1alpha2
 kind: Configuration
 metadata:
   name: example
@@ -17,4 +17,4 @@
   --delete-timeout 45s      \
   --error-timeout 45s       \
   --exec-timeout 45s
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/configuration/options/values/index.html b/main/configuration/options/values/index.html index 727f04333..87f5b8d4d 100644 --- a/main/configuration/options/values/index.html +++ b/main/configuration/options/values/index.html @@ -1,2 +1,2 @@ - External values - Chainsaw
Skip to content

External values

Chainsaw can pass arbitrary values when running tests using the --values flag. Values will be available to tests under the $values binding.

Configuration

With file

Note

Values can't be configured with a configuration file.

With flags

chainsaw test --values ./values.yaml
-
\ No newline at end of file + External values - Chainsaw
Skip to content

External values

Chainsaw can pass arbitrary values when running tests using the --values flag. Values will be available to tests under the $values binding.

Configuration

With file

Note

Values can't be configured with a configuration file.

With flags

chainsaw test --values ./values.yaml
+
\ No newline at end of file diff --git a/main/examples/concurrency/index.html b/main/examples/concurrency/index.html index 7b2c12586..b82a72906 100644 --- a/main/examples/concurrency/index.html +++ b/main/examples/concurrency/index.html @@ -1,4 +1,4 @@ - Concurrency control - Chainsaw
Skip to content

Concurrency control

By default, Chainsaw will run tests in parallel.

The number of concurrent tests can be configured globally using a configuration file or with the --parallel flag.

Alternatively, the concurrent nature of a test can specified at the test level:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Concurrency control - Chainsaw      

Concurrency control

By default, Chainsaw will run tests in parallel.

The number of concurrent tests can be configured globally using a configuration file or with the --parallel flag.

Alternatively, the concurrent nature of a test can specified at the test level:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -7,4 +7,4 @@
   # default value is `true`
   concurrent: false
   # ...
-

All non-concurrent tests are executed first, followed by the concurrent tests running in parallel.

\ No newline at end of file +

All non-concurrent tests are executed first, followed by the concurrent tests running in parallel.

\ No newline at end of file diff --git a/main/examples/crds/index.html b/main/examples/crds/index.html index 352b32e67..7ff431610 100644 --- a/main/examples/crds/index.html +++ b/main/examples/crds/index.html @@ -1,4 +1,4 @@ - Work with CRDs - Chainsaw
Skip to content

Work with CRDs

New CRDs are not immediately available for use in the Kubernetes API until the Kubernetes API has acknowledged them.

If a CRD is being defined inside of a test step, be sure to wait for it to appear.

The test below applies a CRD and waits for it to become available:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Work with CRDs - Chainsaw      

Work with CRDs

New CRDs are not immediately available for use in the Kubernetes API until the Kubernetes API has acknowledged them.

If a CRD is being defined inside of a test step, be sure to wait for it to appear.

The test below applies a CRD and waits for it to become available:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -34,4 +34,4 @@
               singular: issue
             storedVersions:
             - v1alpha1
-

The CRD can be used in subsequent steps.

\ No newline at end of file +

The CRD can be used in subsequent steps.

\ No newline at end of file diff --git a/main/examples/events/index.html b/main/examples/events/index.html index e3c18a062..ff601d197 100644 --- a/main/examples/events/index.html +++ b/main/examples/events/index.html @@ -1,4 +1,4 @@ - Work with events - Chainsaw
Skip to content

Work with events

Kubernetes events are regular Kubernetes objects and can be asserted on just like any other object:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Work with events - Chainsaw      

Work with events

Kubernetes events are regular Kubernetes objects and can be asserted on just like any other object:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -16,4 +16,4 @@
             apiVersion: v1
             kind: Pod
             name: my-pod
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/examples/index.html b/main/examples/index.html index 9b8e3bec1..0261362f1 100644 --- a/main/examples/index.html +++ b/main/examples/index.html @@ -1 +1 @@ - Examples - Chainsaw
Skip to content

Examples

Info

Select an item in the navigation menu to browse a specific page.

\ No newline at end of file + Examples - Chainsaw
Skip to content

Examples

Info

Select an item in the navigation menu to browse a specific page.

\ No newline at end of file diff --git a/main/examples/inline/index.html b/main/examples/inline/index.html index 6bd142124..060c6eac3 100644 --- a/main/examples/inline/index.html +++ b/main/examples/inline/index.html @@ -1,4 +1,4 @@ - Inline resources - Chainsaw
Skip to content

Inline resources

When an operation needs to reference a resource, it can do so using a file path or directly specify the resource inline using the resource field.

The test below is equivalent to our first test:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Inline resources - Chainsaw      

Inline resources

When an operation needs to reference a resource, it can do so using a file path or directly specify the resource inline using the resource field.

The test below is equivalent to our first test:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -21,4 +21,4 @@
             name: quick-start
           data:
             foo: bar
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/examples/kube-version/index.html b/main/examples/kube-version/index.html index a405b7c41..5f1d9e45b 100644 --- a/main/examples/kube-version/index.html +++ b/main/examples/kube-version/index.html @@ -1,4 +1,4 @@ - Check Kubernetes version - Chainsaw
Skip to content

Check Kubernetes version

The test below fetches the Kubernetes cluster version using the x_k8s_server_version function. It then uses the minor version retrieved to adapt an assertion based on the value in the $minorversion binding.

Tip

You can implement a ternary operator in JMESPath using an expression like this:

<condition> && <value-if-true> || <value-if-false>

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Check Kubernetes version - Chainsaw      

Check Kubernetes version

The test below fetches the Kubernetes cluster version using the x_k8s_server_version function. It then uses the minor version retrieved to adapt an assertion based on the value in the $minorversion binding.

Tip

You can implement a ternary operator in JMESPath using an expression like this:

<condition> && <value-if-true> || <value-if-false>

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -34,4 +34,4 @@
               # be 'kubeadm:cluster-admins'.
               kyverno.io/created-by: (($minorversion < `29` && '{"groups":["system:masters","system:authenticated"],"username":"kubernetes-admin"}') || '{"groups":["kubeadm:cluster-admins","system:authenticated"],"username":"kubernetes-admin"}')
             name: pod01
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/examples/label-selectors/index.html b/main/examples/label-selectors/index.html index f764184ce..699226d36 100644 --- a/main/examples/label-selectors/index.html +++ b/main/examples/label-selectors/index.html @@ -1,4 +1,4 @@ - Work with label selectors - Chainsaw
Skip to content

Work with label selectors

Chainsaw can filter the tests to run using label selectors.

You can pass label selectors using the --selector flag when invoking the chainsaw test command.

Given the test below:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Work with label selectors - Chainsaw      

Work with label selectors

Chainsaw can filter the tests to run using label selectors.

You can pass label selectors using the --selector flag when invoking the chainsaw test command.

Given the test below:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: basic
@@ -7,4 +7,4 @@
 spec:
   # ...
 

Invoking Chainsaw with the command below will take the test above into account:

chainsaw test --selector foo=bar
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/examples/multi-cluster/index.html b/main/examples/multi-cluster/index.html index d0a8400ee..8d01ab1d4 100644 --- a/main/examples/multi-cluster/index.html +++ b/main/examples/multi-cluster/index.html @@ -1,4 +1,4 @@ - Multi-cluster setup - Chainsaw
Skip to content

Multi-cluster setup

Chainsaw supports registering and using multiple clusters in tests.

We can also register clusters dynamically and combine this with cluster selection to achieve scenarios where clusters are dynamically allocated in a test step, used in the following steps, and cleaned up at the end.

The following test demonstrates such a scenario by creating a local kind cluster in the first, using it in the second step, and configuring a cleanup script to delete the cluster when the test terminates:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Multi-cluster setup - Chainsaw      

Multi-cluster setup

Chainsaw supports registering and using multiple clusters in tests.

We can also register clusters dynamically and combine this with cluster selection to achieve scenarios where clusters are dynamically allocated in a test step, used in the following steps, and cleaned up at the end.

The following test demonstrates such a scenario by creating a local kind cluster in the first, using it in the second step, and configuring a cleanup script to delete the cluster when the test terminates:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -101,4 +101,4 @@
     | 10:45:10 | example | @cleanup | DELETE    | RUN   | v1/Namespace @ chainsaw-useful-seahorse
     | 10:45:11 | example | @cleanup | DELETE    | OK    | v1/Namespace @ chainsaw-useful-seahorse
     | 10:45:16 | example | @cleanup | DELETE    | DONE  | v1/Namespace @ chainsaw-useful-seahorse
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/examples/negative-testing/index.html b/main/examples/negative-testing/index.html index e619adf8a..52d8f4054 100644 --- a/main/examples/negative-testing/index.html +++ b/main/examples/negative-testing/index.html @@ -1,4 +1,4 @@ - Negative testing - Chainsaw
Skip to content

Negative testing

Negative testing is the process of testing cases that are supposed to fail. That is, a test expects errors to happen and if the expected errors don't occur the test must fail.

Chainsaw supports negative testing by letting you decide what should be considered an error or not.

Tip

By default, Chainsaw will consider an operation failed if there was an error executing it (non-zero exit code in scripts and commands, error returned by the API server when calling into Kubernetes, etc...).

Script case

The test below expects an error and validates the returned error message:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Negative testing - Chainsaw      

Negative testing

Negative testing is the process of testing cases that are supposed to fail. That is, a test expects errors to happen and if the expected errors don't occur the test must fail.

Chainsaw supports negative testing by letting you decide what should be considered an error or not.

Tip

By default, Chainsaw will consider an operation failed if there was an error executing it (non-zero exit code in scripts and commands, error returned by the API server when calling into Kubernetes, etc...).

Script case

The test below expects an error and validates the returned error message:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -43,4 +43,4 @@
               name: quick-start
           check:
             ($error != null): true
-

Using the match field, we can easily target failures related to specific resources.

\ No newline at end of file +

Using the match field, we can easily target failures related to specific resources.

\ No newline at end of file diff --git a/main/examples/non-resource-assertions/index.html b/main/examples/non-resource-assertions/index.html index 01ab832d4..b4724c1cc 100644 --- a/main/examples/non-resource-assertions/index.html +++ b/main/examples/non-resource-assertions/index.html @@ -1,4 +1,4 @@ - Non-resource assertions - Chainsaw
Skip to content

Non-resource assertions

Under certain circumstances, it makes sense to evaluate assertions that do not depend on resources. For example, when asserting the number of nodes in a cluster is equal to a known value.

The test below uses the x_k8s_list function to query the list of nodes in the cluster. It uses the results to compare the number of nodes found with a known number (1 in this case).

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Non-resource assertions - Chainsaw      

Non-resource assertions

Under certain circumstances, it makes sense to evaluate assertions that do not depend on resources. For example, when asserting the number of nodes in a cluster is equal to a known value.

The test below uses the x_k8s_list function to query the list of nodes in the cluster. It uses the results to compare the number of nodes found with a known number (1 in this case).

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -9,4 +9,4 @@
         resource:
           (x_k8s_list($client, 'v1', 'Node')):
             (length(items)): 1
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/examples/test-output/index.html b/main/examples/test-output/index.html index 056834b8c..7c7bc2813 100644 --- a/main/examples/test-output/index.html +++ b/main/examples/test-output/index.html @@ -1,4 +1,4 @@ - Test command output - Chainsaw
Skip to content

Test command output

Chainsaw can be used to easily check terminal output from CLIs and other commands. This is useful in that convoluted bash scripts involving chaining together tools like grep can be avoided or at least minimized to only complex use cases. Output to both stdout and stderr can be checked for a given string or precise contents.

Checking Output Contains

One basic use case for content checking is that the output simply contains a given string or piece of content. For example, you might want to run automated tests on a CLI binary you build to ensure that a given command produces output that contains some content you specify somewhere in the output. Let's use the following output from the kubectl version command to show these examples.

kubectl version
+ Test command output - Chainsaw      

Test command output

Chainsaw can be used to easily check terminal output from CLIs and other commands. This is useful in that convoluted bash scripts involving chaining together tools like grep can be avoided or at least minimized to only complex use cases. Output to both stdout and stderr can be checked for a given string or precise contents.

Checking Output Contains

One basic use case for content checking is that the output simply contains a given string or piece of content. For example, you might want to run automated tests on a CLI binary you build to ensure that a given command produces output that contains some content you specify somewhere in the output. Let's use the following output from the kubectl version command to show these examples.

kubectl version
 
 Client Version: v1.28.2
 Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
@@ -76,4 +76,4 @@
           ($error != null): true
           # This checks that the output is exactly as intended.
           ($stderr): "error: unknown command \"foo\" for \"kubectl\"\n\nDid you mean this?\n\ttop"
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/examples/values/index.html b/main/examples/values/index.html index d1d67836f..35c383f7f 100644 --- a/main/examples/values/index.html +++ b/main/examples/values/index.html @@ -1,4 +1,4 @@ - Pass data to tests - Chainsaw
Skip to content

Pass data to tests

Chainsaw can pass arbitrary values when running tests using the --values flag. Values will be available to tests under the $values binding.

This is useful when a test needs to be configured externally.

Reference external data

The test below expects the $value.foo to be provided when chainsaw is invoked.

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Pass data to tests - Chainsaw      

Pass data to tests

Chainsaw can pass arbitrary values when running tests using the --values flag. Values will be available to tests under the $values binding.

This is useful when a test needs to be configured externally.

Reference external data

The test below expects the $value.foo to be provided when chainsaw is invoked.

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -13,4 +13,4 @@
 

Use heredoc

chainsaw test --values - <<EOF
 foo: bar
 EOF
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/general/bindings/index.html b/main/general/bindings/index.html index bea9bd1ee..6e1339722 100644 --- a/main/general/bindings/index.html +++ b/main/general/bindings/index.html @@ -1,4 +1,4 @@ - Bindings - Chainsaw
Skip to content

Bindings

You can think of bindings as a side context where you can store and retrieve data by name.

This is particularly useful when some data is only known at runtime. For example, to pass data from one operation to another, to implement resource templating, to fetch data from an external system, or anything that needs to be computed at runtime.

Syntax

The test below illustrates bindings declaration at different levels:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Bindings - Chainsaw      

Bindings

You can think of bindings as a side context where you can store and retrieve data by name.

This is particularly useful when some data is only known at runtime. For example, to pass data from one operation to another, to implement resource templating, to fetch data from an external system, or anything that needs to be computed at runtime.

Syntax

The test below illustrates bindings declaration at different levels:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -24,4 +24,4 @@
         - name: GREETINGS
           value: (join(' ', [$hello, $chainsaw, 'is', $awesome]))
         content: echo $GREETINGS
-

Reference

Browse the reference documentation to see the syntax details and where bindings can be declared.

Inheritance

Bindings can be configured at the test, step or operation level.

All bindings configured at a given level are automatically inherited at lower levels.

Immutability

Bindings are immutable. This means two bindings can have the same name without overwriting each other.

When a binding is registered it potentially hides other bindings with the same name.

When this binding goes out of scope, previously registered bindings with the same name become visible again.

Templating

Both name and value of a binding can use templating.

Built-in bindings

Chainsaw offers some built-in bindings you can directly use in your tests, steps and operations.

Browse the built-in bindings list to find available bindings.

\ No newline at end of file +

Reference

Browse the reference documentation to see the syntax details and where bindings can be declared.

Inheritance

Bindings can be configured at the test, step or operation level.

All bindings configured at a given level are automatically inherited at lower levels.

Immutability

Bindings are immutable. This means two bindings can have the same name without overwriting each other.

When a binding is registered it potentially hides other bindings with the same name.

When this binding goes out of scope, previously registered bindings with the same name become visible again.

Templating

Both name and value of a binding can use templating.

Built-in bindings

Chainsaw offers some built-in bindings you can directly use in your tests, steps and operations.

Browse the built-in bindings list to find available bindings.

\ No newline at end of file diff --git a/main/general/checks/index.html b/main/general/checks/index.html index 2eefa2a73..e4996afcf 100644 --- a/main/general/checks/index.html +++ b/main/general/checks/index.html @@ -1,4 +1,4 @@ - Operation checks - Chainsaw
Skip to content

Operation checks

Considering an operation's success or failure is not always as simple as checking an error code.

  • Sometimes an operation can fail but the failure is what you expected, hence the operation should be reported as successful.
  • Sometimes an operation can succeed but the result is not what you expected, in this case, the operation should be reported as a failure.

To support those kinds of use cases, some operations support additional checks to evaluate the operation result against an assertion tree.

Input model

Different operations have a different model passed through the assertion tree.

Please consult the Built-in bindings reference documentation to learn what is available depending on the operation.

Expect vs Check

While a simple check is enough to determine the result of a single operation, we needed a more advanced construct to cover apply, create, delete, patch and update operations. Those operations can operate on files containing multiple resources and every resource can lead to a different result and expectation.

Check

The example below uses a simple check. The operation is expected to fail (($error != null): true):

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Operation checks - Chainsaw      

Operation checks

Considering an operation's success or failure is not always as simple as checking an error code.

  • Sometimes an operation can fail but the failure is what you expected, hence the operation should be reported as successful.
  • Sometimes an operation can succeed but the result is not what you expected, in this case, the operation should be reported as a failure.

To support those kinds of use cases, some operations support additional checks to evaluate the operation result against an assertion tree.

Input model

Different operations have a different model passed through the assertion tree.

Please consult the Built-in bindings reference documentation to learn what is available depending on the operation.

Expect vs Check

While a simple check is enough to determine the result of a single operation, we needed a more advanced construct to cover apply, create, delete, patch and update operations. Those operations can operate on files containing multiple resources and every resource can lead to a different result and expectation.

Check

The example below uses a simple check. The operation is expected to fail (($error != null): true):

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -33,4 +33,4 @@
             # - succeed if the operation failed
             # - fail if the operation succeeded
             ($error != null): true
-

In the test above, only config maps are expected to fail. If the resources.yaml file contains other type of resources they are supposed to be created without error (if an error happens for a non config map resource, the operation will be considered a failure).

\ No newline at end of file +

In the test above, only config maps are expected to fail. If the resources.yaml file contains other type of resources they are supposed to be created without error (if an error happens for a non config map resource, the operation will be considered a failure).

\ No newline at end of file diff --git a/main/general/inheritance/index.html b/main/general/inheritance/index.html index 2621d9193..3e3a00df7 100644 --- a/main/general/inheritance/index.html +++ b/main/general/inheritance/index.html @@ -1,4 +1,4 @@ - Inheritance - Chainsaw
Skip to content

Inheritance

Chainsaw has a concept of levels and most of the configuration elements and dynamic elements are inherited from one layer to the next in one way or another.

Levels

flowchart TD
+ Inheritance - Chainsaw      

Inheritance

Chainsaw has a concept of levels and most of the configuration elements and dynamic elements are inherited from one layer to the next in one way or another.

Levels

flowchart TD
     Configuration -. Configuration elements are inherited in tests .-> Test
     Test -. Test elements are inherited in test steps .-> Step
-    Step -. Step elements are inherited in step operations .-> Operation

Configuration

The first layer comes from the Chainsaw configuration. You can think about this layer as the global scope and a way to configure how Chainsaw will behave globally.

Under certain circumstances, lower layers will be allowed to consume and/or override elements from upper layers.

Test

At the test level, you can override or create new elements. They will only be visible to the test, steps and operations that are part of it.

In any case, tests are strongly isolated and have no way to communicate with or depend on other tests.

Step

Again, at the step level, you can override or create new elements and they will only be visible to the step and operations that are part of it.

Operation

At the operation level, you can override or create new elements and use them in the operation itself.

Immutability

Even if elements are inherited, they are immutable.

Some elements can be overridden but never overwritten.

Outputs

Inheritance always flows from one level to the next and never propagates back to the upper levels.

There's no exception to this rule, but the only case where one operation can communicate with other ones is when using outputs.

\ No newline at end of file + Step -. Step elements are inherited in step operations .-> Operation

Configuration

The first layer comes from the Chainsaw configuration. You can think about this layer as the global scope and a way to configure how Chainsaw will behave globally.

Under certain circumstances, lower layers will be allowed to consume and/or override elements from upper layers.

Test

At the test level, you can override or create new elements. They will only be visible to the test, steps and operations that are part of it.

In any case, tests are strongly isolated and have no way to communicate with or depend on other tests.

Step

Again, at the step level, you can override or create new elements and they will only be visible to the step and operations that are part of it.

Operation

At the operation level, you can override or create new elements and use them in the operation itself.

Immutability

Even if elements are inherited, they are immutable.

Some elements can be overridden but never overwritten.

Outputs

Inheritance always flows from one level to the next and never propagates back to the upper levels.

There's no exception to this rule, but the only case where one operation can communicate with other ones is when using outputs.

\ No newline at end of file diff --git a/main/general/namespace/index.html b/main/general/namespace/index.html index 37998b728..7700244b6 100644 --- a/main/general/namespace/index.html +++ b/main/general/namespace/index.html @@ -1,4 +1,4 @@ - Test namespace - Chainsaw
Skip to content

Test namespace

By default, Chainsaw will create an ephemeral namespace with a random name for each test, unless a specific namespace name is provided at the global or test level.

Selection

Global

One way to control the namespace used to run tests is to specify the name in the Chainsaw configuration Namespace options.

If a namespace name is specified at the configuration level Chainsaw will use it to run the tests (unless an individual test overrides the namespace name).

Per test

If the test name is specified in a test spec, Chainsaw will use it to run the test regardless of whether a namespace name was configured at the global level.

Random

If no namespace name was specified at the global or test level, Chainsaw will create a random one for the lifetime of the test.

Cleanup

As with any other resource, Chainsaw will clean up the namespace only if the namespace was created by Chainsaw.

If the namespace already exists when the test starts, Chainsaw will use it to run the test but won't delete it after the test terminates.

Template

A namespace template can be provided at the global or test level.

This is useful if you want to make something specific with the namespace Chainsaw creates (add labels, add annotations, etc...).

Tip

A namespace template specified at the test level takes precedence over the namespace template specified at the global level.

Namespace injection

Because the name of the namespace is only known at runtime, depending on the resource being manipulated, Chainsaw will eventually inject the namespace name, except if:

  • the resource already has a namespace specified
  • the resource is a clustered resource

Example

The resource below is a namespaced one and has no namespace specified. Chainsaw will automatically inject the namespace name in it:

apiVersion: v1
+ Test namespace - Chainsaw      

Test namespace

By default, Chainsaw will create an ephemeral namespace with a random name for each test, unless a specific namespace name is provided at the global or test level.

Selection

Global

One way to control the namespace used to run tests is to specify the name in the Chainsaw configuration Namespace options.

If a namespace name is specified at the configuration level Chainsaw will use it to run the tests (unless an individual test overrides the namespace name).

Per test

If the test name is specified in a test spec, Chainsaw will use it to run the test regardless of whether a namespace name was configured at the global level.

Random

If no namespace name was specified at the global or test level, Chainsaw will create a random one for the lifetime of the test.

Cleanup

As with any other resource, Chainsaw will clean up the namespace only if the namespace was created by Chainsaw.

If the namespace already exists when the test starts, Chainsaw will use it to run the test but won't delete it after the test terminates.

Template

A namespace template can be provided at the global or test level.

This is useful if you want to make something specific with the namespace Chainsaw creates (add labels, add annotations, etc...).

Tip

A namespace template specified at the test level takes precedence over the namespace template specified at the global level.

Namespace injection

Because the name of the namespace is only known at runtime, depending on the resource being manipulated, Chainsaw will eventually inject the namespace name, except if:

  • the resource already has a namespace specified
  • the resource is a clustered resource

Example

The resource below is a namespaced one and has no namespace specified. Chainsaw will automatically inject the namespace name in it:

apiVersion: v1
 kind: ConfigMap
 metadata:
   name: chainsaw-quick-start
@@ -7,4 +7,4 @@
   # Chainsaw will automatically inject the test namespace
 data:
   foo: bar
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/general/outputs/index.html b/main/general/outputs/index.html index be930d4ef..ce755fd28 100644 --- a/main/general/outputs/index.html +++ b/main/general/outputs/index.html @@ -1,4 +1,4 @@ - Outputs - Chainsaw
Skip to content

Outputs

Operation outputs can be useful for communicating and reusing computation results across operations.

Chainsaw evaluates outputs after an operation has finished executing. The results of output evaluations are registered in the bindings and are made available for the following operations.

Syntax

Basic

The test below illustrates output usage:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Outputs - Chainsaw      

Outputs

Operation outputs can be useful for communicating and reusing computation results across operations.

Chainsaw evaluates outputs after an operation has finished executing. The results of output evaluations are registered in the bindings and are made available for the following operations.

Syntax

Basic

The test below illustrates output usage:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -71,4 +71,4 @@
         - name: INPUT
           value: ($OUTPUT)
         content: echo $INPUT
-

Reference

Browse the reference documentation to see the syntax details and where outputs can be declared.

Templating

Both name and value of an output can use templating.

\ No newline at end of file +

Reference

Browse the reference documentation to see the syntax details and where outputs can be declared.

Templating

Both name and value of an output can use templating.

\ No newline at end of file diff --git a/main/general/references/index.html b/main/general/references/index.html index 68613f0d4..0b7effcd8 100644 --- a/main/general/references/index.html +++ b/main/general/references/index.html @@ -1,4 +1,4 @@ - References - Chainsaw
Skip to content

References

Chainsaw tests often need to reference resources. Including references in tests can be done in multiple ways.

Inline

One way to declare a resource is to do it directly inside the test definition:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ References - Chainsaw      

References

Chainsaw tests often need to reference resources. Including references in tests can be done in multiple ways.

Inline

One way to declare a resource is to do it directly inside the test definition:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -45,4 +45,4 @@
     - apply:
         # use an URL
         file: https://raw.githubusercontent.com/kyverno/chainsaw/main/testdata/step/configmap.yaml
-

Cardinality

When using file-based references, it is important to note that the referenced file(s) can declare multiple resources. Internally, Chainsaw will duplicate the operation once per resource.

This is important to keep this in mind, especially when working with bindings and outputs. Bindings and outputs will be evaluated for every operation instance.

\ No newline at end of file +

Cardinality

When using file-based references, it is important to note that the referenced file(s) can declare multiple resources. Internally, Chainsaw will duplicate the operation once per resource.

This is important to keep this in mind, especially when working with bindings and outputs. Bindings and outputs will be evaluated for every operation instance.

\ No newline at end of file diff --git a/main/general/templating/index.html b/main/general/templating/index.html index 5e8e3c4d4..eb7a25fd6 100644 --- a/main/general/templating/index.html +++ b/main/general/templating/index.html @@ -1,4 +1,4 @@ - Templating - Chainsaw
Skip to content

Templating

Chainsaw simplifies dynamic configuration with native templating support.

In the past, users have created all sorts of hacks using tools like envsubst for dynamic substitution of env-variables. Those workarounds usually lack flexibility and introduce new problems like hiding the real resources from Chainsaw, preventing it from cleaning resources properly.

Templating in Chainsaw solves exactly this kind of problem.

Syntax

Tip

Resource templating is heavily based on bindings and uses JMESPath language.

Bindings

In the template below, we are using the $namespace binding at two different places, effectively injecting the ephemeral namespace name in the name and the data.foo fields:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Templating - Chainsaw      

Templating

Chainsaw simplifies dynamic configuration with native templating support.

In the past, users have created all sorts of hacks using tools like envsubst for dynamic substitution of env-variables. Those workarounds usually lack flexibility and introduce new problems like hiding the real resources from Chainsaw, preventing it from cleaning resources properly.

Templating in Chainsaw solves exactly this kind of problem.

Syntax

Tip

Resource templating is heavily based on bindings and uses JMESPath language.

Bindings

In the template below, we are using the $namespace binding at two different places, effectively injecting the ephemeral namespace name in the name and the data.foo fields:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -26,4 +26,4 @@
           name: (join('-', [$namespace, 'cm']))
         data:
           foo: bar
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/guides/kuttl-migration/index.html b/main/guides/kuttl-migration/index.html index cf4627ca5..7545009d4 100644 --- a/main/guides/kuttl-migration/index.html +++ b/main/guides/kuttl-migration/index.html @@ -1,3 +1,3 @@ - Migration from KUTTL - Chainsaw
Skip to content

Migration from KUTTL

Overview

The chainsaw migrate kuttl tests and chainsaw migrate kuttl config commands are designed for the migration of KUTTL tests to Chainsaw.

Reference documentation

You can view the full command documentation here.

Examples

Migrate tests

The command below will migrate KUTTL tests to Chainsaw and overwrite original files with converted ones.

chainsaw migrate kuttl tests path/to/kuttl/tests --save --cleanup
+ Migration from KUTTL - Chainsaw      

Migration from KUTTL

Overview

The chainsaw migrate kuttl tests and chainsaw migrate kuttl config commands are designed for the migration of KUTTL tests to Chainsaw.

Reference documentation

You can view the full command documentation here.

Examples

Migrate tests

The command below will migrate KUTTL tests to Chainsaw and overwrite original files with converted ones.

chainsaw migrate kuttl tests path/to/kuttl/tests --save --cleanup
 

This will generate a chainsaw-test.yaml for every KUTTL test discovered.

Migrate configuration

The command below will migrate a KUTTL test suite file to the corresponding Chainsaw Configuration.

chainsaw migrate kuttl config path/to/kuttl/testsuite --save --cleanup
-

This will generate a .chainsaw.yaml configuration file.

\ No newline at end of file +

This will generate a .chainsaw.yaml configuration file.

\ No newline at end of file diff --git a/main/guides/lint/index.html b/main/guides/lint/index.html index 08df4bc40..12787f906 100644 --- a/main/guides/lint/index.html +++ b/main/guides/lint/index.html @@ -1,4 +1,4 @@ - Lint tests - Chainsaw
Skip to content

Lint tests

Overview

Chainsaw comes with a lint command to detect ill-formated tests.

Reference documentation

You can view the full command documentation here.

Usage

To build the docs of a test, Chainsaw provides the chainsaw lint test -f path/to/chainsaw-test.yaml command.

chainsaw lint test -f - <<EOF
+ Lint tests - Chainsaw      

Lint tests

Overview

Chainsaw comes with a lint command to detect ill-formated tests.

Reference documentation

You can view the full command documentation here.

Usage

To build the docs of a test, Chainsaw provides the chainsaw lint test -f path/to/chainsaw-test.yaml command.

chainsaw lint test -f - <<EOF
 apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
@@ -11,4 +11,4 @@
 EOF
 
Processing input...
 The document is valid
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/guides/test-docs/index.html b/main/guides/test-docs/index.html index 493bf8d07..8ca5de7d8 100644 --- a/main/guides/test-docs/index.html +++ b/main/guides/test-docs/index.html @@ -1,4 +1,4 @@ - Building test docs - Chainsaw
Skip to content

Building test docs

Overview

Chainsaw makes it simple to build the documentation of your tests.

As test suites grow, it becomes important to document what a test does and how it is supposed to work.

Going through the implementation of a test to understand its purpose is not an efficient strategy.

Reference documentation

You can view the full command documentation here.

Usage

To build the docs of a test, Chainsaw provides the chainsaw build docs command.

chainsaw build docs --test-dir path/to/chainsaw/tests
+ Building test docs - Chainsaw      

Building test docs

Overview

Chainsaw makes it simple to build the documentation of your tests.

As test suites grow, it becomes important to document what a test does and how it is supposed to work.

Going through the implementation of a test to understand its purpose is not an efficient strategy.

Reference documentation

You can view the full command documentation here.

Usage

To build the docs of a test, Chainsaw provides the chainsaw build docs command.

chainsaw build docs --test-dir path/to/chainsaw/tests
 

This will automatically discover tests and document steps and operations in try, catch and finally statements.

The description field

Additionally, you can set the description field in:

  • TestSpec
  • TestStepSpec
  • Operation
  • Catch
  • Finally

Chainsaw will output them nicely in the built docs.

Example

See below for an example test and the corresponding built docs.

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
@@ -14,4 +14,4 @@
     - description: Check the configmap content.
       assert:
         file: configmap-assert.yaml
-

Test: basic

This is a very simple test that creates a configmap and checks the content is as expected.

Steps

# Name Try Catch Finally
1 step-1 2 0 0

Step: step-1

This step applies the configmap in the cluster and checks the configmap content.

Try

# Operation Description
1 apply Create the configmap.
2 assert Check the configmap content.
\ No newline at end of file +

Test: basic

This is a very simple test that creates a configmap and checks the content is as expected.

Steps

# Name Try Catch Finally
1 step-1 2 0 0

Step: step-1

This step applies the configmap in the cluster and checks the configmap content.

Try

# Operation Description
1 apply Create the configmap.
2 assert Check the configmap content.
\ No newline at end of file diff --git a/main/index.html b/main/index.html index 97ad60d97..55c8821ea 100644 --- a/main/index.html +++ b/main/index.html @@ -1,4 +1,4 @@ - Chainsaw - Stronger end-to-end testing tool - Chainsaw

Kyverno Chainsaw

Kyverno end to end testing tool!

  • Used internally to continuously test Kyverno
  • Entirely low code and declarative
  • Provides an advanced and flexible assertion model
  • Run it locally or in your CI/CD pipelines
  • ... and much more!
Get started Learn more

Everything you would expect

  • Easy to install

    Install locally using a package manager like brew or nix, or simply download the binary from one of our releases. If you want to run using a Docker image, we have that too.

  • Easy to use

    Write tests in minutes, not hours. All it takes is a YAML file to define the steps of a test. Chainsaw will do the rest, no need to learn a programing language or write a single line of code!

  • Comprehensive reporting

    Understand and diagnose failures easily, thanks to a comprehensive output showing precisely what failed and why. Generate JUnit compatible reports to integrate with other test reporting tools.

  • Resource templating

    Kubernetes is all about resouces and tests need to work with resources. Chainsaw has built-in support for bindings, operation outputs and resource templating to describe complex test scenarios.

  • Positive testing

    Create, update, delete resources and assert your controller reconciles the desired and observed states in the expected way.

  • Negative testing

    Try submitting invalid resources, invalid changes, or other disallowed actions and make sure they are rejected.

  • Stay focused

    Focus on the software you are building, write test scenarios using YAML and let Chainsaw tell you what passes or not. Integrate in your CI pipeline to prevent regressions and release with better confidence.

  • Multi cluster

    Native support for tests involving multiple clusters, either static or dynamically created ones, make Chainsaw an excellent tool for testing highly complex environments and architectures.

Widely adopted


Running all end to end tests for both Kyverno and the policies catalog.


Chainsaw replaced and improved upon our bash test framework for testing the RbacDefinition CRD.


Chainsaw cut down on hacks, improved code-reuse and enhanced test debugging.


Chainsaw enabled easier e2e testing and CI debugging after replacing kuttl.


Chainsaw helped a lot for declarative assertion of Redis Cluster state against various e2e test.


Chainsaw replaced Kuttl, and helped us get rid of many unreadable bash scripts.


Chainsaw replaced Kuttl, helped us improve logging and remove native kubectl calls.


Chainsaw cranked up the tempo, making our e2e tests dance to a rhythm of reliability and efficiency.


Chainsaw replaced Kuttl and made our e2e tests much more readable and easier to debug.

Discover Chainsaw in video

Watch this excellent review to discover the unique power of Chainsaw

\ No newline at end of file +

Kyverno Chainsaw

Kyverno end to end testing tool!

  • Used internally to continuously test Kyverno
  • Entirely low code and declarative
  • Provides an advanced and flexible assertion model
  • Run it locally or in your CI/CD pipelines
  • ... and much more!
Get started Learn more

Everything you would expect

  • Easy to install

    Install locally using a package manager like brew or nix, or simply download the binary from one of our releases. If you want to run using a Docker image, we have that too.

  • Easy to use

    Write tests in minutes, not hours. All it takes is a YAML file to define the steps of a test. Chainsaw will do the rest, no need to learn a programing language or write a single line of code!

  • Comprehensive reporting

    Understand and diagnose failures easily, thanks to a comprehensive output showing precisely what failed and why. Generate JUnit compatible reports to integrate with other test reporting tools.

  • Resource templating

    Kubernetes is all about resouces and tests need to work with resources. Chainsaw has built-in support for bindings, operation outputs and resource templating to describe complex test scenarios.

  • Positive testing

    Create, update, delete resources and assert your controller reconciles the desired and observed states in the expected way.

  • Negative testing

    Try submitting invalid resources, invalid changes, or other disallowed actions and make sure they are rejected.

  • Stay focused

    Focus on the software you are building, write test scenarios using YAML and let Chainsaw tell you what passes or not. Integrate in your CI pipeline to prevent regressions and release with better confidence.

  • Multi cluster

    Native support for tests involving multiple clusters, either static or dynamically created ones, make Chainsaw an excellent tool for testing highly complex environments and architectures.

Widely adopted


Running all end to end tests for both Kyverno and the policies catalog.


Chainsaw replaced and improved upon our bash test framework for testing the RbacDefinition CRD.


Chainsaw cut down on hacks, improved code-reuse and enhanced test debugging.


Chainsaw enabled easier e2e testing and CI debugging after replacing kuttl.


Chainsaw helped a lot for declarative assertion of Redis Cluster state against various e2e test.


Chainsaw replaced Kuttl, and helped us get rid of many unreadable bash scripts.


Chainsaw replaced Kuttl, helped us improve logging and remove native kubectl calls.


Chainsaw cranked up the tempo, making our e2e tests dance to a rhythm of reliability and efficiency.


Chainsaw replaced Kuttl and made our e2e tests much more readable and easier to debug.

Discover Chainsaw in video

Watch this excellent review to discover the unique power of Chainsaw

\ No newline at end of file diff --git a/main/operations/apply/index.html b/main/operations/apply/index.html index 4b53255ce..5fe61e9f0 100644 --- a/main/operations/apply/index.html +++ b/main/operations/apply/index.html @@ -1,4 +1,4 @@ - Apply - Chainsaw
Skip to content

Apply

The apply operation defines resources that should be applied to a Kubernetes cluster. If the resource does not exist yet it will be created, otherwise, it will be configured to match the provided configuration.

Configuration

The full structure of the Apply is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Apply - Chainsaw      

Apply

The apply operation defines resources that should be applied to a Kubernetes cluster. If the resource does not exist yet it will be created, otherwise, it will be configured to match the provided configuration.

Configuration

The full structure of the Apply is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -67,4 +67,4 @@
             # - succeed if the operation failed
             # - fail if the operation succeeded
             ($error != null): true
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/assert/index.html b/main/operations/assert/index.html index bf7d87b74..ee57b51a4 100644 --- a/main/operations/assert/index.html +++ b/main/operations/assert/index.html @@ -1,4 +1,4 @@ - Assert - Chainsaw
Skip to content

Assert

The assert operation allows you to specify conditions that should hold true for a successful test.

For example, after applying resources, you might want to ensure that a particular pod is running or a service is accessible.

Configuration

The full structure of the Assert is documented here.

Features

Supported features
Bindings support ✅
Outputs support ❌
Templating support ❌ | ✅
Operation checks support ❌

Templating

When working with assert and error operations, the content is already an assertion tree and therefore mostly represents a logical operation. An exception to this rule is for fields participating in the resource selection process.

For this reason, only elements used for looking up the resources from the cluster will be considered for templating. That is, apiVersion, kind, name, namespace and labels.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Assert - Chainsaw      

Assert

The assert operation allows you to specify conditions that should hold true for a successful test.

For example, after applying resources, you might want to ensure that a particular pod is running or a service is accessible.

Configuration

The full structure of the Assert is documented here.

Features

Supported features
Bindings support ✅
Outputs support ❌
Templating support ❌ | ✅
Operation checks support ❌

Templating

When working with assert and error operations, the content is already an assertion tree and therefore mostly represents a logical operation. An exception to this rule is for fields participating in the resource selection process.

For this reason, only elements used for looking up the resources from the cluster will be considered for templating. That is, apiVersion, kind, name, namespace and labels.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -47,4 +47,4 @@
             name: foo
           spec:
             (replicas > 3): true
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/command/index.html b/main/operations/command/index.html index ad737eb84..431517f44 100644 --- a/main/operations/command/index.html +++ b/main/operations/command/index.html @@ -1,4 +1,4 @@ - Command - Chainsaw
Skip to content

Command

The command operation provides a mean to execute a specific command during the test step.

Warning

Command arguments are not going through shell expansion.

It's crucial to consider potential differences in behavior, as Chainsaw may interpret them differently compared to regular shell environments.

Configuration

The full structure of the Command is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ❌
Operation checks support ✅

KUBECONFIG

  • Unless --no-cluster is specified, Chainsaw always executes commands in the context of a temporary KUBECONFIG, built from the configured target cluster.
  • This specific KUBECONFIG has a single cluster, auth info and context configured (all named chainsaw).

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Command - Chainsaw      

Command

The command operation provides a mean to execute a specific command during the test step.

Warning

Command arguments are not going through shell expansion.

It's crucial to consider potential differences in behavior, as Chainsaw may interpret them differently compared to regular shell environments.

Configuration

The full structure of the Command is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ❌
Operation checks support ✅

KUBECONFIG

  • Unless --no-cluster is specified, Chainsaw always executes commands in the context of a temporary KUBECONFIG, built from the configured target cluster.
  • This specific KUBECONFIG has a single cluster, auth info and context configured (all named chainsaw).

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -25,4 +25,4 @@
           # - succeed if the operation failed
           # - fail if the operation succeeded
           ($error != null): true
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/create/index.html b/main/operations/create/index.html index 30eac884f..a86182ce1 100644 --- a/main/operations/create/index.html +++ b/main/operations/create/index.html @@ -1,4 +1,4 @@ - Create - Chainsaw
Skip to content

Create

The create operation defines resources that should be created in a Kubernetes cluster.

If the resource to be created already exists in the cluster, the step will fail.

Configuration

The full structure of the Create is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Create - Chainsaw      

Create

The create operation defines resources that should be created in a Kubernetes cluster.

If the resource to be created already exists in the cluster, the step will fail.

Configuration

The full structure of the Create is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -67,4 +67,4 @@
             # - succeed if the operation failed
             # - fail if the operation succeeded
             ($error != null): true
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/delete/index.html b/main/operations/delete/index.html index 7dfa1bd4e..1b768294e 100644 --- a/main/operations/delete/index.html +++ b/main/operations/delete/index.html @@ -1,4 +1,4 @@ - Delete - Chainsaw
Skip to content

Delete

The delete operation defines resources that should be deleted from a Kubernetes cluster.

Warning

The propagation policy is forced to Background because some types default to Orphan (this is the case for unmanaged jobs for example) and we don't want to let dangling pods run in the cluster after cleanup.

Configuration

The full structure of the Delete is documented here.

Features

Supported features
Bindings support ✅
Outputs support ❌
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Delete - Chainsaw      

Delete

The delete operation defines resources that should be deleted from a Kubernetes cluster.

Warning

The propagation policy is forced to Background because some types default to Orphan (this is the case for unmanaged jobs for example) and we don't want to let dangling pods run in the cluster after cleanup.

Configuration

The full structure of the Delete is documented here.

Features

Supported features
Bindings support ✅
Outputs support ❌
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -38,4 +38,4 @@
             # - succeed if the operation failed
             # - fail if the operation succeeded
             ($error != null): true
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/error/index.html b/main/operations/error/index.html index 24759abfd..d7e8d4d23 100644 --- a/main/operations/error/index.html +++ b/main/operations/error/index.html @@ -1,4 +1,4 @@ - Error - Chainsaw
Skip to content

Error

The error operation lets you define a set of expected errors for a test step. If any of these errors occur during the test, they are treated as expected outcomes. However, if an error that's not on this list occurs, it will be treated as a test failure.

Configuration

The full structure of the Error is documented here.

Features

Supported features
Bindings support ✅
Outputs support ❌
Templating support ❌ | ✅
Operation checks support ❌

Templating

When working with assert and error operations, the content is already an assertion tree and therefore mostly represents a logical operation. An exception to this rule is for fields participating in the resource selection process.

For this reason, only elements used for looking up the resources from the cluster will be considered for templating. That is, apiVersion, kind, name, namespace and labels.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Error - Chainsaw      

Error

The error operation lets you define a set of expected errors for a test step. If any of these errors occur during the test, they are treated as expected outcomes. However, if an error that's not on this list occurs, it will be treated as a test failure.

Configuration

The full structure of the Error is documented here.

Features

Supported features
Bindings support ✅
Outputs support ❌
Templating support ❌ | ✅
Operation checks support ❌

Templating

When working with assert and error operations, the content is already an assertion tree and therefore mostly represents a logical operation. An exception to this rule is for fields participating in the resource selection process.

For this reason, only elements used for looking up the resources from the cluster will be considered for templating. That is, apiVersion, kind, name, namespace and labels.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -47,4 +47,4 @@
             name: foo
           spec:
             (replicas > 3): true
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/helpers/describe/index.html b/main/operations/helpers/describe/index.html index 03bfa437e..468648af2 100644 --- a/main/operations/helpers/describe/index.html +++ b/main/operations/helpers/describe/index.html @@ -1,4 +1,4 @@ - Describe - Chainsaw
Skip to content

Describe

Show details of a specific resource or group of resources.

Configuration

The full structure of the Describe resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Clustered resources

When used with a clustered resource, the namespace is ignored and is not added to the corresponding kubectl command.

Test namespace

When used with a namespaced resource, Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

When used with a namespaced resource, it is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Describe - Chainsaw      

Describe

Show details of a specific resource or group of resources.

Configuration

The full structure of the Describe resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Clustered resources

When used with a clustered resource, the namespace is ignored and is not added to the corresponding kubectl command.

Test namespace

When used with a namespaced resource, Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

When used with a namespaced resource, it is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -63,4 +63,4 @@
         apiVersion: v1
         kind: Pod
         showEvents: false
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/helpers/events/index.html b/main/operations/helpers/events/index.html index 06c48388c..7a398f536 100644 --- a/main/operations/helpers/events/index.html +++ b/main/operations/helpers/events/index.html @@ -1,4 +1,4 @@ - Events - Chainsaw
Skip to content

Events

Display one or many events.

Configuration

The full structure of the Events resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Test namespace

When used with a namespaced resource, Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

When used with a namespaced resource, it is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Events - Chainsaw      

Events

Display one or many events.

Configuration

The full structure of the Events resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Test namespace

When used with a namespaced resource, Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

When used with a namespaced resource, it is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -66,4 +66,4 @@
     catch:
     - events:
         format: json
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/helpers/get/index.html b/main/operations/helpers/get/index.html index c147e2a8f..22681f4f5 100644 --- a/main/operations/helpers/get/index.html +++ b/main/operations/helpers/get/index.html @@ -1,4 +1,4 @@ - Get - Chainsaw
Skip to content

Get

Display one or many resources.

Configuration

The full structure of the Get resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Clustered resources

When used with a clustered resource, the namespace is ignored and is not added to the corresponding kubectl command.

Test namespace

When used with a namespaced resource, Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

When used with a namespaced resource, it is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Get - Chainsaw      

Get

Display one or many resources.

Configuration

The full structure of the Get resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Clustered resources

When used with a clustered resource, the namespace is ignored and is not added to the corresponding kubectl command.

Test namespace

When used with a namespaced resource, Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

When used with a namespaced resource, it is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -63,4 +63,4 @@
         apiVersion: v1
         kind: Pod
         format: json
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/helpers/index.html b/main/operations/helpers/index.html index f3b48e109..6ec7389c1 100644 --- a/main/operations/helpers/index.html +++ b/main/operations/helpers/index.html @@ -1 +1 @@ - Kubectl helpers - Chainsaw
Skip to content

Kubectl helpers

Kubectl helpers are declarative versions of kubectl imperative commands.

Implementation

Helpers are implemented as syntactic sugars.

They are translated into their corresponding kubectl commands and executed as such.

KUBECONFIG

  • Chainsaw always executes commands in the context of a temporary KUBECONFIG, built from the configured target cluster.
  • This specific KUBECONFIG has a single cluster, auth info and context configured (all named chainsaw).

Helpers

\ No newline at end of file + Kubectl helpers - Chainsaw
Skip to content

Kubectl helpers

Kubectl helpers are declarative versions of kubectl imperative commands.

Implementation

Helpers are implemented as syntactic sugars.

They are translated into their corresponding kubectl commands and executed as such.

KUBECONFIG

  • Chainsaw always executes commands in the context of a temporary KUBECONFIG, built from the configured target cluster.
  • This specific KUBECONFIG has a single cluster, auth info and context configured (all named chainsaw).

Helpers

\ No newline at end of file diff --git a/main/operations/helpers/logs/index.html b/main/operations/helpers/logs/index.html index 8f8cbd2fa..401fe4e69 100644 --- a/main/operations/helpers/logs/index.html +++ b/main/operations/helpers/logs/index.html @@ -1,4 +1,4 @@ - Pods logs - Chainsaw
Skip to content

Pods logs

Print the logs for a container in a pod or specified resource.

Configuration

The full structure of the PodLogs resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Test namespace

Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

It is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Pods logs - Chainsaw      

Pods logs

Print the logs for a container in a pod or specified resource.

Configuration

The full structure of the PodLogs resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Test namespace

Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

It is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -63,4 +63,4 @@
     catch:
     - podLogs:
         container: nginx
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/helpers/wait/index.html b/main/operations/helpers/wait/index.html index 2e0528468..e19556c46 100644 --- a/main/operations/helpers/wait/index.html +++ b/main/operations/helpers/wait/index.html @@ -1,4 +1,4 @@ - Wait - Chainsaw
Skip to content

Wait

Wait for a specific condition on one or many resources.

Configuration

The full structure of the Wait resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Clustered resources

When used with a clustered resource, the namespace is ignored and is not added to the corresponding kubectl command.

All resources

If you don't specify a name or a selector, the wait operation will consider all resources.

Test namespace

When used with a namespaced resource, Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

When used with a namespaced resource, it is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Wait - Chainsaw      

Wait

Wait for a specific condition on one or many resources.

Configuration

The full structure of the Wait resource is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Clustered resources

When used with a clustered resource, the namespace is ignored and is not added to the corresponding kubectl command.

All resources

If you don't specify a name or a selector, the wait operation will consider all resources.

Test namespace

When used with a namespaced resource, Chainsaw will default the scope to the ephemeral test namespace.

All namespaces

When used with a namespaced resource, it is possible to consider all namespaces in the cluster by setting namespace: '*'.

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -92,4 +92,4 @@
         apiVersion: v1
         kind: Pod
         format: json
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/index.html b/main/operations/index.html index 23ad61de7..045b7efcf 100644 --- a/main/operations/index.html +++ b/main/operations/index.html @@ -1,4 +1,4 @@ - Operations - Chainsaw
Skip to content

Operations

Chainsaw supports the following operations:

Helpers

Chainsaw also supports kubectl helpers.

Properties

Action unicity

Every operation must consist of a single action.

While it is syntactically possible to create an operation with multiple actions, Chainsaw will verify and reject tests if operations containing multiple actions are found.

The reasoning behind this intentional choice is that it becomes harder to understand in which order actions will be executed when an operation consists of multiple actions. For this reason, operations consisting of multiple actions are not allowed.

Common fields

Continue on error

The continueOnError field determines whether a test step should continue executing or not if the operation fails (in any case the test will be marked as failed).

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Operations - Chainsaw      

Operations

Chainsaw supports the following operations:

Helpers

Chainsaw also supports kubectl helpers.

Properties

Action unicity

Every operation must consist of a single action.

While it is syntactically possible to create an operation with multiple actions, Chainsaw will verify and reject tests if operations containing multiple actions are found.

The reasoning behind this intentional choice is that it becomes harder to understand in which order actions will be executed when an operation consists of multiple actions. For this reason, operations consisting of multiple actions are not allowed.

Common fields

Continue on error

The continueOnError field determines whether a test step should continue executing or not if the operation fails (in any case the test will be marked as failed).

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -27,4 +27,4 @@
     - description: Waits a couple of seconds
       sleep:
         duration: 3s
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/patch/index.html b/main/operations/patch/index.html index d60dc3afb..8819e13e5 100644 --- a/main/operations/patch/index.html +++ b/main/operations/patch/index.html @@ -1,4 +1,4 @@ - Patch - Chainsaw
Skip to content

Patch

The patch operation defines resources that should be modified in a Kubernetes cluster.

If the resource to be modified does not exist in the cluster, the step will fail.

Configuration

The full structure of the Patch is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Patch - Chainsaw      

Patch

The patch operation defines resources that should be modified in a Kubernetes cluster.

If the resource to be modified does not exist in the cluster, the step will fail.

Configuration

The full structure of the Patch is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -67,4 +67,4 @@
             # - succeed if the operation failed
             # - fail if the operation succeeded
             ($error != null): true
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/script/index.html b/main/operations/script/index.html index e14f8eeb3..f3ad23a4a 100644 --- a/main/operations/script/index.html +++ b/main/operations/script/index.html @@ -1,4 +1,4 @@ - Script - Chainsaw
Skip to content

Script

The script operation provides a means to run a script during the test step.

Configuration

The full structure of the Script is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ❌
Operation checks support ✅

KUBECONFIG

  • Unless --no-cluster is specified, Chainsaw always executes commands in the context of a temporary KUBECONFIG, built from the configured target cluster.
  • This specific KUBECONFIG has a single cluster, auth info and context configured (all named chainsaw).

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Script - Chainsaw      

Script

The script operation provides a means to run a script during the test step.

Configuration

The full structure of the Script is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ❌
Operation checks support ✅

KUBECONFIG

  • Unless --no-cluster is specified, Chainsaw always executes commands in the context of a temporary KUBECONFIG, built from the configured target cluster.
  • This specific KUBECONFIG has a single cluster, auth info and context configured (all named chainsaw).

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -23,4 +23,4 @@
           # - succeed if the operation failed
           # - fail if the operation succeeded
           ($error != null): true
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/sleep/index.html b/main/operations/sleep/index.html index 0ce0c041f..db029d273 100644 --- a/main/operations/sleep/index.html +++ b/main/operations/sleep/index.html @@ -1,4 +1,4 @@ - Sleep - Chainsaw
Skip to content

Sleep

The sleep operation provides a means to sleep for a configured duration.

Configuration

The full structure of the Sleep is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Sleep - Chainsaw      

Sleep

The sleep operation provides a means to sleep for a configured duration.

Configuration

The full structure of the Sleep is documented here.

Features

Supported features
Bindings support ❌
Outputs support ❌
Templating support ❌
Operation checks support ❌

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -7,4 +7,4 @@
   - try:
     - sleep:
         duration: 30s
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/operations/update/index.html b/main/operations/update/index.html index d6dd2fdcf..c7093d76d 100644 --- a/main/operations/update/index.html +++ b/main/operations/update/index.html @@ -1,4 +1,4 @@ - Update - Chainsaw
Skip to content

Update

The update operation defines resources that should be updated in a Kubernetes cluster.

If the resource to be updated doesn't exist in the cluster, the step will fail.

Configuration

The full structure of the Update is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Update - Chainsaw      

Update

The update operation defines resources that should be updated in a Kubernetes cluster.

If the resource to be updated doesn't exist in the cluster, the step will fail.

Configuration

The full structure of the Update is documented here.

Features

Supported features
Bindings support ✅
Outputs support ✅
Templating support ✅
Operation checks support ✅

Examples

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -67,4 +67,4 @@
             # - succeed if the operation failed
             # - fail if the operation succeeded
             ($error != null): true
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/quick-start/assertion-trees/index.html b/main/quick-start/assertion-trees/index.html index 423ad9427..180adae83 100644 --- a/main/quick-start/assertion-trees/index.html +++ b/main/quick-start/assertion-trees/index.html @@ -1,4 +1,4 @@ - Use assertions - Chainsaw
Skip to content

Use assertions

Chainsaw allows declaring complex assertions with a simple and no-code approach, allowing assertions based on comparisons beyond simple equality, working with arrays, and other scenarios that could not be achieved before.

Tip

Under the hood, Chainsaw uses kyverno-json assertion trees. Refer to the assertion trees documentation for more details on the supported syntax.

Basic assertion

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Use assertions - Chainsaw      

Use assertions

Chainsaw allows declaring complex assertions with a simple and no-code approach, allowing assertions based on comparisons beyond simple equality, working with arrays, and other scenarios that could not be achieved before.

Tip

Under the hood, Chainsaw uses kyverno-json assertion trees. Refer to the assertion trees documentation for more details on the supported syntax.

Basic assertion

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -128,4 +128,4 @@
     +    uid: 118abe16-ec42-4894-83db-64479c4aac6f
       spec: {}
 | 09:56:20 | deployment | step-1   | TRY       | DONE  |
-

Next step

To continue our exploration of the main Chainsaw features, let's look at bindings and resource templating next.

\ No newline at end of file +

Next step

To continue our exploration of the main Chainsaw features, let's look at bindings and resource templating next.

\ No newline at end of file diff --git a/main/quick-start/bindings/index.html b/main/quick-start/bindings/index.html index 5f7b4e3df..f84650629 100644 --- a/main/quick-start/bindings/index.html +++ b/main/quick-start/bindings/index.html @@ -1,4 +1,4 @@ - Use bindings - Chainsaw
Skip to content

Use bindings

You can think of bindings as a side context where you can store and retrieve data based on keys.

This is particularly useful when some data is only known at runtime. For example, to pass data from one operation to another, to implement resource templating, to fetch data from an external system, etc.

Chainsaw offers some built-in bindings you can directly use in your tests but you can also create your own bindings if needed.

Inheritance

Bindings can be configured at the test, step or operation level.

All bindings configured at a given level are automatically inherited in child levels.

JMESPath

Chainsaw uses the JMESPath language, and bindings are implemented using lexical scoping.

Immutability

Bindings are immutable. This means two bindings can have the same name without overwriting each other.

When a binding is registered it potentially hides other bindings with the same name.

When this binding goes out of scope, previously registered bindings with the same name become visible again.

Built-in bindings

The $namespace binding is a good example of a built-in binding provided by Chainsaw. It contains the name of the ephemeral namespace used to execute a test (by default Chainsaw will create an ephemeral namespace for each test).

In the operation below, we are assigning the value of the $namespace binding to an environment variable, and echo it in a script:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Use bindings - Chainsaw      

Use bindings

You can think of bindings as a side context where you can store and retrieve data based on keys.

This is particularly useful when some data is only known at runtime. For example, to pass data from one operation to another, to implement resource templating, to fetch data from an external system, etc.

Chainsaw offers some built-in bindings you can directly use in your tests but you can also create your own bindings if needed.

Inheritance

Bindings can be configured at the test, step or operation level.

All bindings configured at a given level are automatically inherited in child levels.

JMESPath

Chainsaw uses the JMESPath language, and bindings are implemented using lexical scoping.

Immutability

Bindings are immutable. This means two bindings can have the same name without overwriting each other.

When a binding is registered it potentially hides other bindings with the same name.

When this binding goes out of scope, previously registered bindings with the same name become visible again.

Built-in bindings

The $namespace binding is a good example of a built-in binding provided by Chainsaw. It contains the name of the ephemeral namespace used to execute a test (by default Chainsaw will create an ephemeral namespace for each test).

In the operation below, we are assigning the value of the $namespace binding to an environment variable, and echo it in a script:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -38,4 +38,4 @@
         - name: GREETINGS
           value: (join(' ', [$hello, $chainsaw, 'is', $awesome]))
         content: echo $GREETINGS
-

Next step

Let's see how bindings can be useful with resource templating.

\ No newline at end of file +

Next step

Let's see how bindings can be useful with resource templating.

\ No newline at end of file diff --git a/main/quick-start/cleanup/index.html b/main/quick-start/cleanup/index.html index e8e8f1a04..13c3d4e3c 100644 --- a/main/quick-start/cleanup/index.html +++ b/main/quick-start/cleanup/index.html @@ -1,4 +1,4 @@ - Control your cleanup - Chainsaw
Skip to content

Control your cleanup

Unless configured differently, by default Chainsaw will automatically remove the resources it created after a test finishes.

Cleanup happens in reverse order of creation (created last, cleaned up first). This is important, especially when the controller being tested makes use of finalizers.

Overriding cleanup timeout

Note that Chainsaw performs a blocking deletion, that is, it will wait until the resource is not present anymore in the cluster before proceeding with the next resource cleanup.

Timeout

A global cleanup timeout can be defined at the configuration level or using command line flags.

It can also be overridden on a per-test or per-step basis but not at the operation level.

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Control your cleanup - Chainsaw      

Control your cleanup

Unless configured differently, by default Chainsaw will automatically remove the resources it created after a test finishes.

Cleanup happens in reverse order of creation (created last, cleaned up first). This is important, especially when the controller being tested makes use of finalizers.

Overriding cleanup timeout

Note that Chainsaw performs a blocking deletion, that is, it will wait until the resource is not present anymore in the cluster before proceeding with the next resource cleanup.

Timeout

A global cleanup timeout can be defined at the configuration level or using command line flags.

It can also be overridden on a per-test or per-step basis but not at the operation level.

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -52,4 +52,4 @@
     - script:
         content: |
           rm -f ./dynamic
-

Next step

At this point, we covered the main Chainsaw features.

Look at the next steps section to find out what to do next.

\ No newline at end of file +

Next step

At this point, we covered the main Chainsaw features.

Look at the next steps section to find out what to do next.

\ No newline at end of file diff --git a/main/quick-start/completion/index.html b/main/quick-start/completion/index.html index 8acf39e64..768870969 100644 --- a/main/quick-start/completion/index.html +++ b/main/quick-start/completion/index.html @@ -1 +1 @@ - Shell completion - Chainsaw
Skip to content

Shell completion

Once installed, use chainsaw completion command to generate and register the autocompletion script for the specified shell.

Supported shells are:

\ No newline at end of file + Shell completion - Chainsaw
Skip to content

Shell completion

Once installed, use chainsaw completion command to generate and register the autocompletion script for the specified shell.

Supported shells are:

\ No newline at end of file diff --git a/main/quick-start/first-test/index.html b/main/quick-start/first-test/index.html index 2df3cb35c..e372f5d17 100644 --- a/main/quick-start/first-test/index.html +++ b/main/quick-start/first-test/index.html @@ -1,4 +1,4 @@ - Create a test - Chainsaw
Skip to content

Create a test

To create a Chainsaw test all you need to do is to create one (or more) YAML file(s).

The recommended approach is to create one folder per test, with a chainsaw-test.yaml file containing one (or more) test definition(s). The test definition can reference other files in the same folder or anywhere else on the file system as needed.

Tip

While chainsaw supports other syntaxes, we strongly recommend the explicit approach.

What is a test?

To put it simply, a test can be represented as an ordered sequence of test steps.

In turn, a test step can be represented as an ordered sequence of operations.

When one of the operations fails the test is considered failed.

If all operations succeed the test is considered successful.

Let's write our first test

For this quick start, we will create a (very simple) Test with one step and two operations:

  1. Create a ConfigMap from a manifest
  2. Verify the ConfigMap was created and contains the expected data

Follow the instructions below to create the folder and files defining our first test.

Create a test folder

# create test folder
+ Create a test - Chainsaw      

Create a test

To create a Chainsaw test all you need to do is to create one (or more) YAML file(s).

The recommended approach is to create one folder per test, with a chainsaw-test.yaml file containing one (or more) test definition(s). The test definition can reference other files in the same folder or anywhere else on the file system as needed.

Tip

While chainsaw supports other syntaxes, we strongly recommend the explicit approach.

What is a test?

To put it simply, a test can be represented as an ordered sequence of test steps.

In turn, a test step can be represented as an ordered sequence of operations.

When one of the operations fails the test is considered failed.

If all operations succeed the test is considered successful.

Let's write our first test

For this quick start, we will create a (very simple) Test with one step and two operations:

  1. Create a ConfigMap from a manifest
  2. Verify the ConfigMap was created and contains the expected data

Follow the instructions below to create the folder and files defining our first test.

Create a test folder

# create test folder
 mkdir chainsaw-quick-start
 
 # enter test folder
@@ -30,4 +30,4 @@
         # file is relative to the test folder
         file: configmap.yaml
 EOF
-

Next step

Now we have created our first test, you can continue to the next section to execute it.

\ No newline at end of file +

Next step

Now we have created our first test, you can continue to the next section to execute it.

\ No newline at end of file diff --git a/main/quick-start/index.html b/main/quick-start/index.html index c44e4d0b3..cb31d0add 100644 --- a/main/quick-start/index.html +++ b/main/quick-start/index.html @@ -1 +1 @@ - Getting started - Chainsaw
Skip to content

Getting started

Chainsaw is a tool primarily developed to run end-to-end tests in Kubernetes clusters.

It is meant to test Kubernetes operators work as expected by running a sequence of steps and asserting various conditions.

Why we made it?

While developing Kyverno we need to run end-to-end tests to make sure our admission controller works as expected.

A typical Kyverno end-to-end test

Kyverno can validate, mutate and generate resources based on policies installed in a cluster and a typical test is:

  1. Create a policy
  2. Create a resource
  3. Check that Kyverno acted as expected
  4. Cleanup and move to the next test

How to use it?

Chainsaw is built with CI tools in mind - you only really need to download and execute it in your build script.

However, installing it on your local machine is entirely possible.

\ No newline at end of file + Getting started - Chainsaw
Skip to content

Getting started

Chainsaw is a tool primarily developed to run end-to-end tests in Kubernetes clusters.

It is meant to test Kubernetes operators work as expected by running a sequence of steps and asserting various conditions.

Why we made it?

While developing Kyverno we need to run end-to-end tests to make sure our admission controller works as expected.

A typical Kyverno end-to-end test

Kyverno can validate, mutate and generate resources based on policies installed in a cluster and a typical test is:

  1. Create a policy
  2. Create a resource
  3. Check that Kyverno acted as expected
  4. Cleanup and move to the next test

How to use it?

Chainsaw is built with CI tools in mind - you only really need to download and execute it in your build script.

However, installing it on your local machine is entirely possible.

\ No newline at end of file diff --git a/main/quick-start/install/index.html b/main/quick-start/install/index.html index 4adbc985d..16bf6a834 100644 --- a/main/quick-start/install/index.html +++ b/main/quick-start/install/index.html @@ -1,4 +1,4 @@ - Installation - Chainsaw
Skip to content

Installation

You can install the pre-compiled binary (in several ways), compile from sources, or run with Docker.

We also provide a GitHub action to easily install Chainsaw in your workflows.

Install the pre-compiled binary

Homebrew tap

add tap:

brew tap kyverno/chainsaw https://github.com/kyverno/chainsaw
+ Installation - Chainsaw      

Installation

You can install the pre-compiled binary (in several ways), compile from sources, or run with Docker.

We also provide a GitHub action to easily install Chainsaw in your workflows.

Install the pre-compiled binary

Homebrew tap

add tap:

brew tap kyverno/chainsaw https://github.com/kyverno/chainsaw
 

install chainsaw:

brew install kyverno/chainsaw/chainsaw
 

Don't forget to specify the tap name

Homebrew core already has a tool named chainsaw.

Be sure that you specify the tap name when installing to install the right tool.

Manually

Download the pre-compiled binaries for your system from the releases page and copy them to the desired location.

Install using go install

You can install with go install with:

go install github.com/kyverno/chainsaw@latest
 

Run with Docker

Chainsaw is also available as a Docker image which you can pull and run:

docker pull ghcr.io/kyverno/chainsaw:<version>
@@ -20,4 +20,4 @@
   pkgs.kyverno-chainsaw
 ];
 

Using nix-shell

A nix-shell will temporarily modify your $PATH environment variable. This can be used to try a piece of software before deciding to permanently install it. Use the following command to install kyverno-chainsaw :

nix-shell -p kyverno-chainsaw
-

GitHub action

A GitHub action is available to install Chainsaw in your workflows. See the GitHub action dedicated documentation.

\ No newline at end of file +

GitHub action

A GitHub action is available to install Chainsaw in your workflows. See the GitHub action dedicated documentation.

\ No newline at end of file diff --git a/main/quick-start/next-steps/index.html b/main/quick-start/next-steps/index.html index b08e7df3e..1c388fbe8 100644 --- a/main/quick-start/next-steps/index.html +++ b/main/quick-start/next-steps/index.html @@ -1 +1 @@ - Next steps - Chainsaw
Skip to content

Next steps

We covered the main features of Chainsaw in this Getting started sections.

While this should help you understand Chainsaw better, there are a lot of other things Chainsaw can do for you.

Tip

If there's anything you would like to be improved, please reach out, we will be happy to discuss and improve as much as we can.

To continue exploring the capabilities of Chainsaw:

\ No newline at end of file + Next steps - Chainsaw
Skip to content

Next steps

We covered the main features of Chainsaw in this Getting started sections.

While this should help you understand Chainsaw better, there are a lot of other things Chainsaw can do for you.

Tip

If there's anything you would like to be improved, please reach out, we will be happy to discuss and improve as much as we can.

To continue exploring the capabilities of Chainsaw:

\ No newline at end of file diff --git a/main/quick-start/operation-outputs/index.html b/main/quick-start/operation-outputs/index.html index 4d31078b8..b7e35b17d 100644 --- a/main/quick-start/operation-outputs/index.html +++ b/main/quick-start/operation-outputs/index.html @@ -1,4 +1,4 @@ - Use operation outputs - Chainsaw
Skip to content

Use operation outputs

Operation outputs can be useful for communicating and reusing computation results across operations.

Lifetime of outputs

Once an output has been added to the bindings context, this binding will be available to all following operations in the same step.

Currently, outputs do not cross the step boundaries.

Matching

An output supports an optional match field. The match is used to conditionally create a binding.

In the case of applying a file, for example, the file may contain multiple resources. The match can be used to select the resource to use for creating the binding.

Load an existing resource

The example below invokes a kubectl command to get a configmap from the cluster in json format.

The json output is then parsed and added to the $cm binding and the next operation performs an assertion on it by reading the binding instead of querying the cluster.

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Use operation outputs - Chainsaw      

Use operation outputs

Operation outputs can be useful for communicating and reusing computation results across operations.

Lifetime of outputs

Once an output has been added to the bindings context, this binding will be available to all following operations in the same step.

Currently, outputs do not cross the step boundaries.

Matching

An output supports an optional match field. The match is used to conditionally create a binding.

In the case of applying a file, for example, the file may contain multiple resources. The match can be used to select the resource to use for creating the binding.

Load an existing resource

The example below invokes a kubectl command to get a configmap from the cluster in json format.

The json output is then parsed and added to the $cm binding and the next operation performs an assertion on it by reading the binding instead of querying the cluster.

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -37,4 +37,4 @@
         - name: UID
           value: ($cm.metadata.uid)
         content: echo $UID
-

Next step

In the next section, we will look at the three main elements of a test step, the try, catch and finally blocks.

\ No newline at end of file +

Next step

In the next section, we will look at the three main elements of a test step, the try, catch and finally blocks.

\ No newline at end of file diff --git a/main/quick-start/resource-templating/index.html b/main/quick-start/resource-templating/index.html index ff706de9c..b6e28dbb1 100644 --- a/main/quick-start/resource-templating/index.html +++ b/main/quick-start/resource-templating/index.html @@ -1,4 +1,4 @@ - Use resource templating - Chainsaw
Skip to content

Use resource templating

Chainsaw simplifies dynamic resource configuration with native resource templating support.

Sometimes things we need to create resources or assertions are only known at runtime.

In the past, users have created all sorts of hacks using tools like envsubst for dynamic substitution of env-variables. Those workarounds usually lack flexibility and introduce new problems like hiding the real resources from Chainsaw, preventing it from cleaning resources properly.

Tip

Resource templating is heavily based on bindings and uses JMESPath language.

Leverage bindings

In the template below, we are using the $namespace binding at two different places, effectively injecting the ephemeral namespace name in the name and the data.foo fields:

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Use resource templating - Chainsaw      

Use resource templating

Chainsaw simplifies dynamic resource configuration with native resource templating support.

Sometimes things we need to create resources or assertions are only known at runtime.

In the past, users have created all sorts of hacks using tools like envsubst for dynamic substitution of env-variables. Those workarounds usually lack flexibility and introduce new problems like hiding the real resources from Chainsaw, preventing it from cleaning resources properly.

Tip

Resource templating is heavily based on bindings and uses JMESPath language.

Leverage bindings

In the template below, we are using the $namespace binding at two different places, effectively injecting the ephemeral namespace name in the name and the data.foo fields:

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -26,4 +26,4 @@
           name: (join('-', [$namespace, 'cm']))
         data:
           foo: bar
-

Next step

Combining bindings and templates with operation outputs allows even more flexibility to pass arbitrary data from one operation to another.

\ No newline at end of file +

Next step

Combining bindings and templates with operation outputs allows even more flexibility to pass arbitrary data from one operation to another.

\ No newline at end of file diff --git a/main/quick-start/resources/index.html b/main/quick-start/resources/index.html index 48036f96a..f52e27038 100644 --- a/main/quick-start/resources/index.html +++ b/main/quick-start/resources/index.html @@ -1 +1 @@ - Additional resources - Chainsaw
Skip to content
\ No newline at end of file + Additional resources - Chainsaw
Skip to content
\ No newline at end of file diff --git a/main/quick-start/run-tests/index.html b/main/quick-start/run-tests/index.html index a37db4b35..1772e03fe 100644 --- a/main/quick-start/run-tests/index.html +++ b/main/quick-start/run-tests/index.html @@ -1,4 +1,4 @@ - Run tests - Chainsaw
Skip to content

Run tests

After installing chainsaw and writing tests, the next natural step is to run Chainsaw to execute the tests.

Create a local cluster

To use Chainsaw you will need a Kubernetes cluster, Chainsaw won't create one for you.

Not a cluster management tool

We consider this is not the responsibility of Chainsaw to manage clusters. There are plenty of solutions to create and manage local clusters that will do that better than Chainsaw.

The command below will create a local cluster using kind. Use the tool of your choice or directly jump to the next section if you already have a KUBECONFIG configured and pointing to a valid cluster.

# create cluster
+ Run tests - Chainsaw      

Run tests

After installing chainsaw and writing tests, the next natural step is to run Chainsaw to execute the tests.

Create a local cluster

To use Chainsaw you will need a Kubernetes cluster, Chainsaw won't create one for you.

Not a cluster management tool

We consider this is not the responsibility of Chainsaw to manage clusters. There are plenty of solutions to create and manage local clusters that will do that better than Chainsaw.

The command below will create a local cluster using kind. Use the tool of your choice or directly jump to the next section if you already have a KUBECONFIG configured and pointing to a valid cluster.

# create cluster
 kind create cluster --image "kindest/node:v1.29.4"
 

Run Chainsaw

Now you can run the chainsaw test command.

> chainsaw test
 
@@ -51,4 +51,4 @@
 - Failed  tests 0
 - Skipped tests 0
 Done.
-

Tip

Chainsaw expects a path to the test folder and will discover tests by analyzing files recursively. When no path is provided Chainsaw will use the current path by default (.).

Next step

The test above demonstrates the most basic usage of Chainsaw. In the next sections, we will look at the main features that make Chainsaw a very unique tool.

\ No newline at end of file +

Tip

Chainsaw expects a path to the test folder and will discover tests by analyzing files recursively. When no path is provided Chainsaw will use the current path by default (.).

Next step

The test above demonstrates the most basic usage of Chainsaw. In the next sections, we will look at the main features that make Chainsaw a very unique tool.

\ No newline at end of file diff --git a/main/quick-start/timeouts/index.html b/main/quick-start/timeouts/index.html index 28ca6b721..c9684cd50 100644 --- a/main/quick-start/timeouts/index.html +++ b/main/quick-start/timeouts/index.html @@ -1,4 +1,4 @@ - Control your timeouts - Chainsaw
Skip to content

Control your timeouts

Timeouts in Chainsaw are specified per type of operation. This is handy because the timeout varies greatly depending on the nature of an operation.

For example, applying a manifest in a cluster is expected to be reasonably fast, while validating a resource can be a long operation.

Inheritance

Timeouts can be configured globally and at the test, step or individual operation level.

All timeouts configured at a given level are automatically inherited in child levels. When looking up a timeout, the most specific one takes precedence over the others.

Info

To learn more about timeouts and how to configure global values, see the timeouts configuration page.

At the test level

When a timeout is configured at the test level it will apply to all operations and steps in the test, unless overridden at a more specific level.

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Control your timeouts - Chainsaw      

Control your timeouts

Timeouts in Chainsaw are specified per type of operation. This is handy because the timeout varies greatly depending on the nature of an operation.

For example, applying a manifest in a cluster is expected to be reasonably fast, while validating a resource can be a long operation.

Inheritance

Timeouts can be configured globally and at the test, step or individual operation level.

All timeouts configured at a given level are automatically inherited in child levels. When looking up a timeout, the most specific one takes precedence over the others.

Info

To learn more about timeouts and how to configure global values, see the timeouts configuration page.

At the test level

When a timeout is configured at the test level it will apply to all operations and steps in the test, unless overridden at a more specific level.

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -105,4 +105,4 @@
           status:
             (conditions[?type == 'Ready']):
             - status: 'True'
-

Next step

In the next section, we will see how Chainsaw manages cleanup.

\ No newline at end of file +

Next step

In the next section, we will see how Chainsaw manages cleanup.

\ No newline at end of file diff --git a/main/quick-start/try-catch/index.html b/main/quick-start/try-catch/index.html index 8cd08095a..0f17e7e02 100644 --- a/main/quick-start/try-catch/index.html +++ b/main/quick-start/try-catch/index.html @@ -1,4 +1,4 @@ - Use try, catch and finally - Chainsaw
Skip to content

Use try, catch and finally

A test step is made of 3 main blocks used to determine the actions Chainsaw will perform when executing the step, depending on operations outcome.

  • The try block (required)
  • The catch block (optional)
  • The finally block (optional)

Operations defined in the try block are executed first, then:

  • If an operation fails to execute, Chainsaw won't execute the remaining operations and will execute all operations defined in the catch block instead (if any).
  • If all operations succeed, Chainsaw will NOT execute operations defined in the catch block (if any).
  • Regardless of the step outcome (success or failure), Chainsaw will execute all operations defined in the finally block (if any).

Note

Note that all operations coming from the catch or finally blocks are executed. If one operation fails, Chainsaw will mark the test as failed and continue executing with the next operation.

Cleanup

At the end of a test, Chainsaw automatically cleans up the resources created during the test (cleanup is done in the opposite order of creation).

All operations from the catch and finally blocks are executed before the cleanup process kicks in. This order allows analyzing the resources that potentially caused the step failure before they are deleted.

Catch

Operations in a catch block are executed only when the step is considered failed.

This is particularly useful to collect additional information to help understand what caused the failure.

In the example below, the test contains a catch block to collect events in the cluster when an operation fails in the step.

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Use try, catch and finally - Chainsaw      

Use try, catch and finally

A test step is made of 3 main blocks used to determine the actions Chainsaw will perform when executing the step, depending on operations outcome.

  • The try block (required)
  • The catch block (optional)
  • The finally block (optional)

Operations defined in the try block are executed first, then:

  • If an operation fails to execute, Chainsaw won't execute the remaining operations and will execute all operations defined in the catch block instead (if any).
  • If all operations succeed, Chainsaw will NOT execute operations defined in the catch block (if any).
  • Regardless of the step outcome (success or failure), Chainsaw will execute all operations defined in the finally block (if any).

Note

Note that all operations coming from the catch or finally blocks are executed. If one operation fails, Chainsaw will mark the test as failed and continue executing with the next operation.

Cleanup

At the end of a test, Chainsaw automatically cleans up the resources created during the test (cleanup is done in the opposite order of creation).

All operations from the catch and finally blocks are executed before the cleanup process kicks in. This order allows analyzing the resources that potentially caused the step failure before they are deleted.

Catch

Operations in a catch block are executed only when the step is considered failed.

This is particularly useful to collect additional information to help understand what caused the failure.

In the example below, the test contains a catch block to collect events in the cluster when an operation fails in the step.

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -38,4 +38,4 @@
     - script:
         content: |
           rm -f ./dynamic
-

Next step

Every operation in a test must be executed in a timely fashion. In the next section, we will see how you can control your timeouts.

\ No newline at end of file +

Next step

Every operation in a test must be executed in a timely fashion. In the next section, we will see how you can control your timeouts.

\ No newline at end of file diff --git a/main/reference/apis/chainsaw.v1alpha1/index.html b/main/reference/apis/chainsaw.v1alpha1/index.html index 85858a69f..407df7331 100644 --- a/main/reference/apis/chainsaw.v1alpha1/index.html +++ b/main/reference/apis/chainsaw.v1alpha1/index.html @@ -1 +1 @@ - chainsaw (v1alpha1) - Chainsaw
Skip to content

v1alpha1

Package v1alpha1 contains API Schema definitions for the v1alpha1 API group.

Resource Types

Configuration

Configuration is the resource that contains the configuration used to run tests.

Field Type Required Inline Description
apiVersion string ✅ chainsaw.kyverno.io/v1alpha1
kind string ✅ Configuration
metadata meta/v1.ObjectMeta

Standard object's metadata.

spec ConfigurationSpec ✅

Configuration spec.

StepTemplate

StepTemplate is the resource that contains a step definition.

Field Type Required Inline Description
apiVersion string ✅ chainsaw.kyverno.io/v1alpha1
kind string ✅ StepTemplate
metadata meta/v1.ObjectMeta

Standard object's metadata.

spec StepTemplateSpec ✅

Test step spec.

Test

Test is the resource that contains a test definition.

Field Type Required Inline Description
apiVersion string ✅ chainsaw.kyverno.io/v1alpha1
kind string ✅ Test
metadata meta/v1.ObjectMeta

Standard object's metadata.

spec TestSpec ✅

Test spec.

ActionBindings

Appears in:

ActionBindings contains bindings options for an action.

Field Type Required Inline Description
bindings []Binding

Bindings defines additional binding key/values.

ActionCheck

Appears in:

ActionCheck contains check for an action.

Field Type Required Inline Description
check policy/v1alpha1.AssertionTree

Check is an assertion tree to validate the operation outcome.

ActionCheckRef

Appears in:

ActionCheckRef contains check reference options for an action.

Field Type Required Inline Description
FileRef FileRef ✅ ✅ No description provided.
resource Projection

Check provides a check used in assertions.

template bool

Template determines whether resources should be considered for templating.

ActionClusters

Appears in:

ActionClusters contains clusters options for an action.

Field Type Required Inline Description
cluster string

Cluster defines the target cluster (will be inherited if not specified).

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

ActionDryRun

Appears in:

ActionDryRun contains dry run options for an action.

Field Type Required Inline Description
dryRun bool

DryRun determines whether the file should be applied in dry run mode.

ActionEnv

Appears in:

ActionEnv contains environment options for an action.

Field Type Required Inline Description
env []Binding

Env defines additional environment variables.

skipLogOutput bool

SkipLogOutput removes the output from the command. Useful for sensitive logs or to reduce noise.

ActionExpectations

Appears in:

ActionExpectations contains expectations for an action.

Field Type Required Inline Description
expect []Expectation

Expect defines a list of matched checks to validate the operation outcome.

ActionFormat

Appears in:

ActionFormat contains format for an action.

Field Type Required Inline Description
format Format

Format determines the output format (json or yaml).

ActionObject

Appears in:

ActionObject contains object selector options for an action.

Field Type Required Inline Description
ObjectType ObjectType ✅ ✅ No description provided.
ActionObjectSelector ActionObjectSelector ✅ ✅ No description provided.

ActionObjectSelector

Appears in:

ActionObjectSelector contains object selector options for an action.

Field Type Required Inline Description
ObjectName ObjectName ✅ ✅ No description provided.
selector Expression

Selector defines labels selector.

ActionOutputs

Appears in:

ActionOutputs contains outputs options for an action.

Field Type Required Inline Description
outputs []Output

Outputs defines output bindings.

ActionResourceRef

Appears in:

ActionResourceRef contains resource reference options for an action.

Field Type Required Inline Description
FileRef FileRef ✅ ✅ No description provided.
resource meta/v1/unstructured.Unstructured

Resource provides a resource to be applied.

template bool

Template determines whether resources should be considered for templating.

ActionTimeout

Appears in:

ActionTimeout contains timeout options for an action.

Field Type Required Inline Description
timeout meta/v1.Duration

Timeout for the operation. Overrides the global timeout set in the Configuration.

Apply

Appears in:

Apply represents a set of configurations or resources that should be applied during testing.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionDryRun ActionDryRun ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionResourceRef ActionResourceRef ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Assert

Appears in:

Assert represents a test condition that is expected to hold true during the testing process.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionCheckRef ActionCheckRef ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Binding

Appears in:

Binding represents a key/value set as a binding in an executing test.

Field Type Required Inline Description
name Expression ✅

Name the name of the binding.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

value Projection ✅

Value value of the binding.

CatchFinally

Appears in:

CatchFinally defines actions to be executed in catch, finally and cleanup blocks.

Field Type Required Inline Description
description string

Description contains a description of the operation.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

podLogs PodLogs

PodLogs determines the pod logs collector to execute.

events Events

Events determines the events collector to execute.

describe Describe

Describe determines the resource describe collector to execute.

wait Wait

Wait determines the resource wait collector to execute.

get Get

Get determines the resource get collector to execute.

delete Delete

Delete represents a deletion operation.

command Command

Command defines a command to run.

script Script

Script defines a script to run.

sleep Sleep

Sleep defines zzzz.

Clusters

(Alias of map[string]github.com/kyverno/chainsaw/pkg/apis/v1alpha1.Cluster)

Appears in:

Clusters defines a cluster map.

Command

Appears in:

Command describes a command to run as a part of a test step.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionCheck ActionCheck ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionEnv ActionEnv ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
entrypoint string ✅

Entrypoint is the command entry point to run.

args []string

Args is the command arguments.

workDir string

WorkDir is the working directory for command.

ConfigurationSpec

Appears in:

ConfigurationSpec contains the configuration used to run tests.

Field Type Required Inline Description
timeouts DefaultTimeouts

Global timeouts configuration. Applies to all tests/test steps if not overridden.

skipDelete bool

If set, do not delete the resources after running the tests (implies SkipClusterDelete).

template bool

Template determines whether resources should be considered for templating.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

failFast bool

FailFast determines whether the test should stop upon encountering the first failure.

parallel int

The maximum number of tests to run at once.

deletionPropagationPolicy meta/v1.DeletionPropagation

DeletionPropagationPolicy decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation.

reportFormat ReportFormatType

ReportFormat determines test report format (JSON

reportPath string

ReportPath defines the path.

reportName string

ReportName defines the name of report to create. It defaults to "chainsaw-report".

namespace string

Namespace defines the namespace to use for tests. If not specified, every test will execute in a random ephemeral namespace unless the namespace is overridden in a the test spec.

namespaceTemplateCompiler policy/v1alpha1.Compiler

NamespaceTemplateCompiler defines the default compiler to use when evaluating expressions.

namespaceTemplate Projection

NamespaceTemplate defines a template to create the test namespace.

fullName bool

FullName makes use of the full test case folder path instead of the folder name.

excludeTestRegex string

ExcludeTestRegex is used to exclude tests based on a regular expression.

includeTestRegex string

IncludeTestRegex is used to include tests based on a regular expression.

repeatCount int

RepeatCount indicates how many times the tests should be executed.

testFile string

TestFile is the name of the file containing the test to run. If no extension is provided, chainsaw will try with .yaml first and .yml if needed.

forceTerminationGracePeriod meta/v1.Duration

ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.

delayBeforeCleanup meta/v1.Duration

DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

catch []CatchFinally

Catch defines what the tests steps will execute when an error happens. This will be combined with catch handlers defined at the test and step levels.

Create

Appears in:

Create represents a set of resources that should be created. If a resource already exists in the cluster it will fail.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionDryRun ActionDryRun ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionResourceRef ActionResourceRef ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

DefaultTimeouts

Appears in:

DefaultTimeouts contains defautl timeouts per operation.

Field Type Required Inline Description
apply meta/v1.Duration

Apply defines the timeout for the apply operation

assert meta/v1.Duration

Assert defines the timeout for the assert operation

cleanup meta/v1.Duration

Cleanup defines the timeout for the cleanup operation

delete meta/v1.Duration

Delete defines the timeout for the delete operation

error meta/v1.Duration

Error defines the timeout for the error operation

exec meta/v1.Duration

Exec defines the timeout for exec operations

Delete

Appears in:

Delete is a reference to an object that should be deleted

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
template bool

Template determines whether resources should be considered for templating.

file Expression

File is the path to the referenced file. This can be a direct path to a file or an expression that matches multiple files, such as "manifest/*.yaml" for all YAML files within the "manifest" directory.

ref ObjectReference

Ref determines objects to be deleted.

deletionPropagationPolicy meta/v1.DeletionPropagation

DeletionPropagationPolicy decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation. Overrides the deletion propagation policy set in the Configuration, the Test and the TestStep.

Describe

Appears in:

Describe defines how to describe resources.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionObject ActionObject ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
showEvents bool

Show Events indicates whether to include related events.

Error

Appears in:

Error represents an anticipated error condition that may arise during testing. Instead of treating such an error as a test failure, it acknowledges it as expected.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionCheckRef ActionCheckRef ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Events

Appears in:

Events defines how to collect events.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionFormat ActionFormat ✅ ✅ No description provided.
ActionObjectSelector ActionObjectSelector ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Expectation

Appears in:

Expectation represents a check to be applied on the result of an operation with a match filter to determine if the verification should be considered.

Field Type Required Inline Description
match policy/v1alpha1.AssertionTree

Match defines the matching statement.

check policy/v1alpha1.AssertionTree ✅

Check defines the verification statement.

Expression

(Alias of string)

Appears in:

Expression defines an expression to be used in string fields.

FileRef

Appears in:

FileRef represents a file reference.

Field Type Required Inline Description
file Expression ✅

File is the path to the referenced file. This can be a direct path to a file or an expression that matches multiple files, such as "manifest/*.yaml" for all YAML files within the "manifest" directory.

Format

(Alias of string)

Appears in:

Format determines the output format (json or yaml).

Get

Appears in:

Get defines how to get resources.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionFormat ActionFormat ✅ ✅ No description provided.
ActionObject ActionObject ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

ObjectName

Appears in:

ObjectName represents an object namespace and name.

Field Type Required Inline Description
namespace Expression

Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/

name Expression

Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

ObjectReference

Appears in:

ObjectReference represents one or more objects with a specific apiVersion and kind. For a single object name and namespace are used to identify the object. For multiple objects use labels.

Field Type Required Inline Description
ObjectType ObjectType ✅ ✅ No description provided.
ObjectName ObjectName ✅ ✅ No description provided.
labels map[string]string

Label selector to match objects to delete

ObjectType

Appears in:

ObjectType represents a specific apiVersion and kind.

Field Type Required Inline Description
apiVersion Expression ✅

API version of the referent.

kind Expression ✅

Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

Operation

Appears in:

Operation defines a single operation, only one action is permitted for a given operation.

Field Type Required Inline Description
OperationBase OperationBase ✅

OperationBase defines common elements to all operations.

apply Apply

Apply represents resources that should be applied for this test step. This can include things like configuration settings or any other resources that need to be available during the test.

assert Assert

Assert represents an assertion to be made. It checks whether the conditions specified in the assertion hold true.

command Command

Command defines a command to run.

create Create

Create represents a creation operation.

delete Delete

Delete represents a deletion operation.

describe Describe

Describe determines the resource describe collector to execute.

error Error

Error represents the expected errors for this test step. If any of these errors occur, the test will consider them as expected; otherwise, they will be treated as test failures.

events Events

Events determines the events collector to execute.

get Get

Get determines the resource get collector to execute.

patch Patch

Patch represents a patch operation.

podLogs PodLogs

PodLogs determines the pod logs collector to execute.

proxy Proxy

Proxy runs a proxy request.

script Script

Script defines a script to run.

sleep Sleep

Sleep defines zzzz.

update Update

Update represents an update operation.

wait Wait

Wait determines the resource wait collector to execute.

OperationBase

Appears in:

OperationBase defines common elements to all operations.

Field Type Required Inline Description
description string

Description contains a description of the operation.

continueOnError bool

ContinueOnError determines whether a test should continue or not in case the operation was not successful. Even if the test continues executing, it will still be reported as failed.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

Output

Appears in:

Output represents an output binding with a match to determine if the binding must be considered or not.

Field Type Required Inline Description
Binding Binding ✅ ✅

Binding determines the binding to create when the match succeeds.

match policy/v1alpha1.AssertionTree

Match defines the matching statement.

Patch

Appears in:

Patch represents a set of resources that should be patched. If a resource doesn't exist yet in the cluster it will fail.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionDryRun ActionDryRun ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionResourceRef ActionResourceRef ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

PodLogs

Appears in:

PodLogs defines how to collect pod logs.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionObjectSelector ActionObjectSelector ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
container Expression

Container in pod to get logs from else --all-containers is used.

tail int

Tail is the number of last lines to collect from pods. If omitted or zero, then the default is 10 if you use a selector, or -1 (all) if you use a pod name. This matches default behavior of kubectl logs.

Projection

Appears in:

Projection can be any type.

Field Type Required Inline Description

Proxy

Appears in:

Proxy defines how to get resources.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
ObjectName ObjectName ✅ ✅ No description provided.
ObjectType ObjectType ✅ ✅ No description provided.
port Expression

TargetPort defines the target port to proxy the request.

path Expression

TargetPath defines the target path to proxy the request.

ReportFormatType

(Alias of string)

Appears in:

Scenario

Appears in:

Scenario defines per scenario bindings.

Field Type Required Inline Description
bindings []Binding

Bindings defines binding key/values.

Script

Appears in:

Script describes a script to run as a part of a test step.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionCheck ActionCheck ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionEnv ActionEnv ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
content string

Content defines a shell script (run with "sh -c ...").

workDir string

WorkDir is the working directory for script.

Sleep

Appears in:

Sleep represents a duration while nothing happens.

Field Type Required Inline Description
duration meta/v1.Duration ✅

Duration is the delay used for sleeping.

StepTemplateSpec

Appears in:

StepTemplateSpec defines the spec of a step template.

Field Type Required Inline Description
bindings []Binding

Bindings defines additional binding key/values.

try []Operation ✅

Try defines what the step will try to execute.

catch []CatchFinally

Catch defines what the step will execute when an error happens.

finally []CatchFinally

Finally defines what the step will execute after the step is terminated.

cleanup []CatchFinally

Cleanup defines what will be executed after the test is terminated.

TestSpec

Appears in:

TestSpec contains the test spec.

Field Type Required Inline Description
description string

Description contains a description of the test.

failFast bool

FailFast determines whether the test should stop upon encountering the first failure.

timeouts Timeouts

Timeouts for the test. Overrides the global timeouts set in the Configuration on a per operation basis.

cluster string

Cluster defines the target cluster (will be inherited if not specified).

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

skip bool

Skip determines whether the test should skipped.

concurrent bool

Concurrent determines whether the test should run concurrently with other tests.

skipDelete bool

SkipDelete determines whether the resources created by the test should be deleted after the test is executed.

template bool

Template determines whether resources should be considered for templating.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

namespace string

Namespace determines whether the test should run in a random ephemeral namespace or not.

namespaceTemplate Projection

NamespaceTemplate defines a template to create the test namespace.

namespaceTemplateCompiler policy/v1alpha1.Compiler

NamespaceTemplateCompiler defines the default compiler to use when evaluating expressions.

scenarios []Scenario

Scenarios defines test scenarios.

bindings []Binding

Bindings defines additional binding key/values.

steps []TestStep ✅

Steps defining the test.

catch []CatchFinally

Catch defines what the steps will execute when an error happens. This will be combined with catch handlers defined at the step level.

forceTerminationGracePeriod meta/v1.Duration

ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.

delayBeforeCleanup meta/v1.Duration

DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.

deletionPropagationPolicy meta/v1.DeletionPropagation

DeletionPropagationPolicy decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation. Overrides the deletion propagation policy set in the Configuration.

TestStep

Appears in:

TestStep contains the test step definition used in a test spec.

Field Type Required Inline Description
name string

Name of the step.

use Use ✅

Use defines a reference to a step template.

TestStepSpec TestStepSpec ✅ ✅

TestStepSpec of the step.

TestStepSpec

Appears in:

TestStepSpec defines the desired state and behavior for each test step.

Field Type Required Inline Description
description string

Description contains a description of the test step.

timeouts Timeouts

Timeouts for the test step. Overrides the global timeouts set in the Configuration and the timeouts eventually set in the Test.

deletionPropagationPolicy meta/v1.DeletionPropagation

DeletionPropagationPolicy decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation. Overrides the deletion propagation policy set in both the Configuration and the Test.

cluster string

Cluster defines the target cluster (will be inherited if not specified).

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

skipDelete bool

SkipDelete determines whether the resources created by the step should be deleted after the test step is executed.

template bool

Template determines whether resources should be considered for templating.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

bindings []Binding

Bindings defines additional binding key/values.

try []Operation

Try defines what the step will try to execute.

catch []CatchFinally

Catch defines what the step will execute when an error happens.

finally []CatchFinally

Finally defines what the step will execute after the step is terminated.

cleanup []CatchFinally

Cleanup defines what will be executed after the test is terminated.

Timeouts

Appears in:

Timeouts contains timeouts per operation.

Field Type Required Inline Description
apply meta/v1.Duration ✅

Apply defines the timeout for the apply operation

assert meta/v1.Duration ✅

Assert defines the timeout for the assert operation

cleanup meta/v1.Duration ✅

Cleanup defines the timeout for the cleanup operation

delete meta/v1.Duration ✅

Delete defines the timeout for the delete operation

error meta/v1.Duration ✅

Error defines the timeout for the error operation

exec meta/v1.Duration ✅

Exec defines the timeout for exec operations

Update

Appears in:

Update represents a set of resources that should be updated. If a resource does not exist in the cluster it will fail.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionDryRun ActionDryRun ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionResourceRef ActionResourceRef ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Use

Appears in:

Use defines a reference to a step template.

Field Type Required Inline Description
template string ✅

Template references a step template.

with With

With defines arguments passed to the step template.

Wait

Appears in:

Wait specifies how to perform wait operations on resources.

Field Type Required Inline Description
ActionTimeout ActionTimeout ✅ ✅ No description provided.
ActionFormat ActionFormat ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionObject ActionObject ✅ ✅ No description provided.
for WaitFor ✅

WaitFor specifies the condition to wait for.

WaitFor

Appears in:

WaitFor specifies the condition to wait for.

Field Type Required Inline Description
deletion WaitForDeletion

Deletion specifies parameters for waiting on a resource's deletion.

condition WaitForCondition

Condition specifies the condition to wait for.

jsonPath WaitForJsonPath

JsonPath specifies the json path condition to wait for.

WaitForCondition

Appears in:

WaitForCondition represents parameters for waiting on a specific condition of a resource.

Field Type Required Inline Description
name Expression ✅

Name defines the specific condition to wait for, e.g., "Available", "Ready".

value Expression

Value defines the specific condition status to wait for, e.g., "True", "False".

WaitForDeletion

Appears in:

WaitForDeletion represents parameters for waiting on a resource's deletion.

WaitForJsonPath

Appears in:

WaitForJsonPath represents parameters for waiting on a json path of a resource.

Field Type Required Inline Description
path Expression ✅

Path defines the json path to wait for, e.g. '{.status.phase}'.

value Expression

Value defines the expected value to wait for, e.g., "Running".

With

Appears in:

With defines arguments passed to step templates.

Field Type Required Inline Description
bindings []Binding

Bindings defines additional binding key/values.

\ No newline at end of file + chainsaw (v1alpha1) - Chainsaw
Skip to content

v1alpha1

Package v1alpha1 contains API Schema definitions for the v1alpha1 API group.

Resource Types

Configuration

Configuration is the resource that contains the configuration used to run tests.

Field Type Required Inline Description
apiVersion string ✅ chainsaw.kyverno.io/v1alpha1
kind string ✅ Configuration
metadata meta/v1.ObjectMeta

Standard object's metadata.

spec ConfigurationSpec ✅

Configuration spec.

StepTemplate

StepTemplate is the resource that contains a step definition.

Field Type Required Inline Description
apiVersion string ✅ chainsaw.kyverno.io/v1alpha1
kind string ✅ StepTemplate
metadata meta/v1.ObjectMeta

Standard object's metadata.

spec StepTemplateSpec ✅

Test step spec.

Test

Test is the resource that contains a test definition.

Field Type Required Inline Description
apiVersion string ✅ chainsaw.kyverno.io/v1alpha1
kind string ✅ Test
metadata meta/v1.ObjectMeta

Standard object's metadata.

spec TestSpec ✅

Test spec.

ActionBindings

Appears in:

ActionBindings contains bindings options for an action.

Field Type Required Inline Description
bindings []Binding

Bindings defines additional binding key/values.

ActionCheck

Appears in:

ActionCheck contains check for an action.

Field Type Required Inline Description
check policy/v1alpha1.AssertionTree

Check is an assertion tree to validate the operation outcome.

ActionCheckRef

Appears in:

ActionCheckRef contains check reference options for an action.

Field Type Required Inline Description
FileRef FileRef ✅ ✅ No description provided.
resource Projection

Check provides a check used in assertions.

template bool

Template determines whether resources should be considered for templating.

ActionClusters

Appears in:

ActionClusters contains clusters options for an action.

Field Type Required Inline Description
cluster string

Cluster defines the target cluster (will be inherited if not specified).

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

ActionDryRun

Appears in:

ActionDryRun contains dry run options for an action.

Field Type Required Inline Description
dryRun bool

DryRun determines whether the file should be applied in dry run mode.

ActionEnv

Appears in:

ActionEnv contains environment options for an action.

Field Type Required Inline Description
env []Binding

Env defines additional environment variables.

skipLogOutput bool

SkipLogOutput removes the output from the command. Useful for sensitive logs or to reduce noise.

ActionExpectations

Appears in:

ActionExpectations contains expectations for an action.

Field Type Required Inline Description
expect []Expectation

Expect defines a list of matched checks to validate the operation outcome.

ActionFormat

Appears in:

ActionFormat contains format for an action.

Field Type Required Inline Description
format Format

Format determines the output format (json or yaml).

ActionObject

Appears in:

ActionObject contains object selector options for an action.

Field Type Required Inline Description
ObjectType ObjectType ✅ ✅ No description provided.
ActionObjectSelector ActionObjectSelector ✅ ✅ No description provided.

ActionObjectSelector

Appears in:

ActionObjectSelector contains object selector options for an action.

Field Type Required Inline Description
ObjectName ObjectName ✅ ✅ No description provided.
selector Expression

Selector defines labels selector.

ActionOutputs

Appears in:

ActionOutputs contains outputs options for an action.

Field Type Required Inline Description
outputs []Output

Outputs defines output bindings.

ActionResourceRef

Appears in:

ActionResourceRef contains resource reference options for an action.

Field Type Required Inline Description
FileRef FileRef ✅ ✅ No description provided.
resource meta/v1/unstructured.Unstructured

Resource provides a resource to be applied.

template bool

Template determines whether resources should be considered for templating.

ActionTimeout

Appears in:

ActionTimeout contains timeout options for an action.

Field Type Required Inline Description
timeout meta/v1.Duration

Timeout for the operation. Overrides the global timeout set in the Configuration.

Apply

Appears in:

Apply represents a set of configurations or resources that should be applied during testing.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionDryRun ActionDryRun ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionResourceRef ActionResourceRef ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Assert

Appears in:

Assert represents a test condition that is expected to hold true during the testing process.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionCheckRef ActionCheckRef ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Binding

Appears in:

Binding represents a key/value set as a binding in an executing test.

Field Type Required Inline Description
name Expression ✅

Name the name of the binding.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

value Projection ✅

Value value of the binding.

CatchFinally

Appears in:

CatchFinally defines actions to be executed in catch, finally and cleanup blocks.

Field Type Required Inline Description
description string

Description contains a description of the operation.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

podLogs PodLogs

PodLogs determines the pod logs collector to execute.

events Events

Events determines the events collector to execute.

describe Describe

Describe determines the resource describe collector to execute.

wait Wait

Wait determines the resource wait collector to execute.

get Get

Get determines the resource get collector to execute.

delete Delete

Delete represents a deletion operation.

command Command

Command defines a command to run.

script Script

Script defines a script to run.

sleep Sleep

Sleep defines zzzz.

Clusters

(Alias of map[string]github.com/kyverno/chainsaw/pkg/apis/v1alpha1.Cluster)

Appears in:

Clusters defines a cluster map.

Command

Appears in:

Command describes a command to run as a part of a test step.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionCheck ActionCheck ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionEnv ActionEnv ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
entrypoint string ✅

Entrypoint is the command entry point to run.

args []string

Args is the command arguments.

workDir string

WorkDir is the working directory for command.

ConfigurationSpec

Appears in:

ConfigurationSpec contains the configuration used to run tests.

Field Type Required Inline Description
timeouts DefaultTimeouts

Global timeouts configuration. Applies to all tests/test steps if not overridden.

skipDelete bool

If set, do not delete the resources after running the tests (implies SkipClusterDelete).

template bool

Template determines whether resources should be considered for templating.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

failFast bool

FailFast determines whether the test should stop upon encountering the first failure.

parallel int

The maximum number of tests to run at once.

deletionPropagationPolicy meta/v1.DeletionPropagation

DeletionPropagationPolicy decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation.

reportFormat ReportFormatType

ReportFormat determines test report format (JSON

reportPath string

ReportPath defines the path.

reportName string

ReportName defines the name of report to create. It defaults to "chainsaw-report".

namespace string

Namespace defines the namespace to use for tests. If not specified, every test will execute in a random ephemeral namespace unless the namespace is overridden in a the test spec.

namespaceTemplateCompiler policy/v1alpha1.Compiler

NamespaceTemplateCompiler defines the default compiler to use when evaluating expressions.

namespaceTemplate Projection

NamespaceTemplate defines a template to create the test namespace.

fullName bool

FullName makes use of the full test case folder path instead of the folder name.

excludeTestRegex string

ExcludeTestRegex is used to exclude tests based on a regular expression.

includeTestRegex string

IncludeTestRegex is used to include tests based on a regular expression.

repeatCount int

RepeatCount indicates how many times the tests should be executed.

testFile string

TestFile is the name of the file containing the test to run. If no extension is provided, chainsaw will try with .yaml first and .yml if needed.

forceTerminationGracePeriod meta/v1.Duration

ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.

delayBeforeCleanup meta/v1.Duration

DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

catch []CatchFinally

Catch defines what the tests steps will execute when an error happens. This will be combined with catch handlers defined at the test and step levels.

Create

Appears in:

Create represents a set of resources that should be created. If a resource already exists in the cluster it will fail.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionDryRun ActionDryRun ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionResourceRef ActionResourceRef ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

DefaultTimeouts

Appears in:

DefaultTimeouts contains defautl timeouts per operation.

Field Type Required Inline Description
apply meta/v1.Duration

Apply defines the timeout for the apply operation

assert meta/v1.Duration

Assert defines the timeout for the assert operation

cleanup meta/v1.Duration

Cleanup defines the timeout for the cleanup operation

delete meta/v1.Duration

Delete defines the timeout for the delete operation

error meta/v1.Duration

Error defines the timeout for the error operation

exec meta/v1.Duration

Exec defines the timeout for exec operations

Delete

Appears in:

Delete is a reference to an object that should be deleted

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
template bool

Template determines whether resources should be considered for templating.

file Expression

File is the path to the referenced file. This can be a direct path to a file or an expression that matches multiple files, such as "manifest/*.yaml" for all YAML files within the "manifest" directory.

ref ObjectReference

Ref determines objects to be deleted.

deletionPropagationPolicy meta/v1.DeletionPropagation

DeletionPropagationPolicy decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation. Overrides the deletion propagation policy set in the Configuration, the Test and the TestStep.

Describe

Appears in:

Describe defines how to describe resources.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionObject ActionObject ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
showEvents bool

Show Events indicates whether to include related events.

Error

Appears in:

Error represents an anticipated error condition that may arise during testing. Instead of treating such an error as a test failure, it acknowledges it as expected.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionCheckRef ActionCheckRef ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Events

Appears in:

Events defines how to collect events.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionFormat ActionFormat ✅ ✅ No description provided.
ActionObjectSelector ActionObjectSelector ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Expectation

Appears in:

Expectation represents a check to be applied on the result of an operation with a match filter to determine if the verification should be considered.

Field Type Required Inline Description
match policy/v1alpha1.AssertionTree

Match defines the matching statement.

check policy/v1alpha1.AssertionTree ✅

Check defines the verification statement.

Expression

(Alias of string)

Appears in:

Expression defines an expression to be used in string fields.

FileRef

Appears in:

FileRef represents a file reference.

Field Type Required Inline Description
file Expression ✅

File is the path to the referenced file. This can be a direct path to a file or an expression that matches multiple files, such as "manifest/*.yaml" for all YAML files within the "manifest" directory.

Format

(Alias of string)

Appears in:

Format determines the output format (json or yaml).

Get

Appears in:

Get defines how to get resources.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionFormat ActionFormat ✅ ✅ No description provided.
ActionObject ActionObject ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

ObjectName

Appears in:

ObjectName represents an object namespace and name.

Field Type Required Inline Description
namespace Expression

Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/

name Expression

Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

ObjectReference

Appears in:

ObjectReference represents one or more objects with a specific apiVersion and kind. For a single object name and namespace are used to identify the object. For multiple objects use labels.

Field Type Required Inline Description
ObjectType ObjectType ✅ ✅ No description provided.
ObjectName ObjectName ✅ ✅ No description provided.
labels map[string]string

Label selector to match objects to delete

ObjectType

Appears in:

ObjectType represents a specific apiVersion and kind.

Field Type Required Inline Description
apiVersion Expression ✅

API version of the referent.

kind Expression ✅

Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

Operation

Appears in:

Operation defines a single operation, only one action is permitted for a given operation.

Field Type Required Inline Description
OperationBase OperationBase ✅

OperationBase defines common elements to all operations.

apply Apply

Apply represents resources that should be applied for this test step. This can include things like configuration settings or any other resources that need to be available during the test.

assert Assert

Assert represents an assertion to be made. It checks whether the conditions specified in the assertion hold true.

command Command

Command defines a command to run.

create Create

Create represents a creation operation.

delete Delete

Delete represents a deletion operation.

describe Describe

Describe determines the resource describe collector to execute.

error Error

Error represents the expected errors for this test step. If any of these errors occur, the test will consider them as expected; otherwise, they will be treated as test failures.

events Events

Events determines the events collector to execute.

get Get

Get determines the resource get collector to execute.

patch Patch

Patch represents a patch operation.

podLogs PodLogs

PodLogs determines the pod logs collector to execute.

proxy Proxy

Proxy runs a proxy request.

script Script

Script defines a script to run.

sleep Sleep

Sleep defines zzzz.

update Update

Update represents an update operation.

wait Wait

Wait determines the resource wait collector to execute.

OperationBase

Appears in:

OperationBase defines common elements to all operations.

Field Type Required Inline Description
description string

Description contains a description of the operation.

continueOnError bool

ContinueOnError determines whether a test should continue or not in case the operation was not successful. Even if the test continues executing, it will still be reported as failed.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

Output

Appears in:

Output represents an output binding with a match to determine if the binding must be considered or not.

Field Type Required Inline Description
Binding Binding ✅ ✅

Binding determines the binding to create when the match succeeds.

match policy/v1alpha1.AssertionTree

Match defines the matching statement.

Patch

Appears in:

Patch represents a set of resources that should be patched. If a resource doesn't exist yet in the cluster it will fail.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionDryRun ActionDryRun ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionResourceRef ActionResourceRef ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

PodLogs

Appears in:

PodLogs defines how to collect pod logs.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionObjectSelector ActionObjectSelector ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
container Expression

Container in pod to get logs from else --all-containers is used.

tail int

Tail is the number of last lines to collect from pods. If omitted or zero, then the default is 10 if you use a selector, or -1 (all) if you use a pod name. This matches default behavior of kubectl logs.

Projection

Appears in:

Projection can be any type.

Field Type Required Inline Description

Proxy

Appears in:

Proxy defines how to get resources.

Field Type Required Inline Description
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
ObjectName ObjectName ✅ ✅ No description provided.
ObjectType ObjectType ✅ ✅ No description provided.
port Expression

TargetPort defines the target port to proxy the request.

path Expression

TargetPath defines the target path to proxy the request.

ReportFormatType

(Alias of string)

Appears in:

Scenario

Appears in:

Scenario defines per scenario bindings.

Field Type Required Inline Description
bindings []Binding

Bindings defines binding key/values.

Script

Appears in:

Script describes a script to run as a part of a test step.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionCheck ActionCheck ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionEnv ActionEnv ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.
content string

Content defines a shell script (run with "sh -c ...").

workDir string

WorkDir is the working directory for script.

Sleep

Appears in:

Sleep represents a duration while nothing happens.

Field Type Required Inline Description
duration meta/v1.Duration ✅

Duration is the delay used for sleeping.

StepTemplateSpec

Appears in:

StepTemplateSpec defines the spec of a step template.

Field Type Required Inline Description
bindings []Binding

Bindings defines additional binding key/values.

try []Operation ✅

Try defines what the step will try to execute.

catch []CatchFinally

Catch defines what the step will execute when an error happens.

finally []CatchFinally

Finally defines what the step will execute after the step is terminated.

cleanup []CatchFinally

Cleanup defines what will be executed after the test is terminated.

TestSpec

Appears in:

TestSpec contains the test spec.

Field Type Required Inline Description
description string

Description contains a description of the test.

failFast bool

FailFast determines whether the test should stop upon encountering the first failure.

timeouts Timeouts

Timeouts for the test. Overrides the global timeouts set in the Configuration on a per operation basis.

cluster string

Cluster defines the target cluster (will be inherited if not specified).

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

skip bool

Skip determines whether the test should skipped.

concurrent bool

Concurrent determines whether the test should run concurrently with other tests.

skipDelete bool

SkipDelete determines whether the resources created by the test should be deleted after the test is executed.

template bool

Template determines whether resources should be considered for templating.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

namespace string

Namespace determines whether the test should run in a random ephemeral namespace or not.

namespaceTemplate Projection

NamespaceTemplate defines a template to create the test namespace.

namespaceTemplateCompiler policy/v1alpha1.Compiler

NamespaceTemplateCompiler defines the default compiler to use when evaluating expressions.

scenarios []Scenario

Scenarios defines test scenarios.

bindings []Binding

Bindings defines additional binding key/values.

steps []TestStep ✅

Steps defining the test.

catch []CatchFinally

Catch defines what the steps will execute when an error happens. This will be combined with catch handlers defined at the step level.

forceTerminationGracePeriod meta/v1.Duration

ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.

delayBeforeCleanup meta/v1.Duration

DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.

deletionPropagationPolicy meta/v1.DeletionPropagation

DeletionPropagationPolicy decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation. Overrides the deletion propagation policy set in the Configuration.

TestStep

Appears in:

TestStep contains the test step definition used in a test spec.

Field Type Required Inline Description
name string

Name of the step.

use Use ✅

Use defines a reference to a step template.

TestStepSpec TestStepSpec ✅ ✅

TestStepSpec of the step.

TestStepSpec

Appears in:

TestStepSpec defines the desired state and behavior for each test step.

Field Type Required Inline Description
description string

Description contains a description of the test step.

timeouts Timeouts

Timeouts for the test step. Overrides the global timeouts set in the Configuration and the timeouts eventually set in the Test.

deletionPropagationPolicy meta/v1.DeletionPropagation

DeletionPropagationPolicy decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation. Overrides the deletion propagation policy set in both the Configuration and the Test.

cluster string

Cluster defines the target cluster (will be inherited if not specified).

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

skipDelete bool

SkipDelete determines whether the resources created by the step should be deleted after the test step is executed.

template bool

Template determines whether resources should be considered for templating.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

bindings []Binding

Bindings defines additional binding key/values.

try []Operation

Try defines what the step will try to execute.

catch []CatchFinally

Catch defines what the step will execute when an error happens.

finally []CatchFinally

Finally defines what the step will execute after the step is terminated.

cleanup []CatchFinally

Cleanup defines what will be executed after the test is terminated.

Timeouts

Appears in:

Timeouts contains timeouts per operation.

Field Type Required Inline Description
apply meta/v1.Duration ✅

Apply defines the timeout for the apply operation

assert meta/v1.Duration ✅

Assert defines the timeout for the assert operation

cleanup meta/v1.Duration ✅

Cleanup defines the timeout for the cleanup operation

delete meta/v1.Duration ✅

Delete defines the timeout for the delete operation

error meta/v1.Duration ✅

Error defines the timeout for the error operation

exec meta/v1.Duration ✅

Exec defines the timeout for exec operations

Update

Appears in:

Update represents a set of resources that should be updated. If a resource does not exist in the cluster it will fail.

Field Type Required Inline Description
ActionBindings ActionBindings ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionDryRun ActionDryRun ✅ ✅ No description provided.
ActionExpectations ActionExpectations ✅ ✅ No description provided.
ActionOutputs ActionOutputs ✅ ✅ No description provided.
ActionResourceRef ActionResourceRef ✅ ✅ No description provided.
ActionTimeout ActionTimeout ✅ ✅ No description provided.

Use

Appears in:

Use defines a reference to a step template.

Field Type Required Inline Description
template string ✅

Template references a step template.

with With

With defines arguments passed to the step template.

Wait

Appears in:

Wait specifies how to perform wait operations on resources.

Field Type Required Inline Description
ActionTimeout ActionTimeout ✅ ✅ No description provided.
ActionFormat ActionFormat ✅ ✅ No description provided.
ActionClusters ActionClusters ✅ ✅ No description provided.
ActionObject ActionObject ✅ ✅ No description provided.
for WaitFor ✅

WaitFor specifies the condition to wait for.

WaitFor

Appears in:

WaitFor specifies the condition to wait for.

Field Type Required Inline Description
deletion WaitForDeletion

Deletion specifies parameters for waiting on a resource's deletion.

condition WaitForCondition

Condition specifies the condition to wait for.

jsonPath WaitForJsonPath

JsonPath specifies the json path condition to wait for.

WaitForCondition

Appears in:

WaitForCondition represents parameters for waiting on a specific condition of a resource.

Field Type Required Inline Description
name Expression ✅

Name defines the specific condition to wait for, e.g., "Available", "Ready".

value Expression

Value defines the specific condition status to wait for, e.g., "True", "False".

WaitForDeletion

Appears in:

WaitForDeletion represents parameters for waiting on a resource's deletion.

WaitForJsonPath

Appears in:

WaitForJsonPath represents parameters for waiting on a json path of a resource.

Field Type Required Inline Description
path Expression ✅

Path defines the json path to wait for, e.g. '{.status.phase}'.

value Expression

Value defines the expected value to wait for, e.g., "Running".

With

Appears in:

With defines arguments passed to step templates.

Field Type Required Inline Description
bindings []Binding

Bindings defines additional binding key/values.

\ No newline at end of file diff --git a/main/reference/apis/chainsaw.v1alpha2/index.html b/main/reference/apis/chainsaw.v1alpha2/index.html index d3501888b..381388ac1 100644 --- a/main/reference/apis/chainsaw.v1alpha2/index.html +++ b/main/reference/apis/chainsaw.v1alpha2/index.html @@ -1 +1 @@ - chainsaw (v1alpha2) - Chainsaw
Skip to content

v1alpha2

Package v1alpha2 contains API Schema definitions for the v1alpha2 API group.

Resource Types

Configuration

Configuration is the resource that contains the configuration used to run tests.

Field Type Required Inline Description
apiVersion string ✅ chainsaw.kyverno.io/v1alpha2
kind string ✅ Configuration
metadata meta/v1.ObjectMeta

Standard object's metadata.

spec ConfigurationSpec ✅

Configuration spec.

CleanupOptions

Appears in:

CleanupOptions contains the configuration used for cleaning up resources.

Field Type Required Inline Description
skipDelete bool

If set, do not delete the resources after running a test.

delayBeforeCleanup meta/v1.Duration

DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.

ConfigurationSpec

Appears in:

ConfigurationSpec contains the configuration used to run tests.

Field Type Required Inline Description
cleanup CleanupOptions

Cleanup contains cleanup configuration.

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

deletion DeletionOptions

Deletion contains the global deletion configuration.

discovery DiscoveryOptions

Discovery contains tests discovery configuration.

error ErrorOptions

Error contains the global error configuration.

execution ExecutionOptions

Execution contains tests execution configuration.

namespace NamespaceOptions

Namespace contains properties for the namespace to use for tests.

report ReportOptions

Report contains properties for the report.

templating TemplatingOptions

Templating contains the templating config.

timeouts DefaultTimeouts

Global timeouts configuration. Applies to all tests/test steps if not overridden.

DeletionOptions

Appears in:

DeletionOptions contains the configuration used for deleting resources.

Field Type Required Inline Description
propagation meta/v1.DeletionPropagation

Propagation decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation.

DiscoveryOptions

Appears in:

DiscoveryOptions contains the discovery configuration used when discovering tests in folders.

Field Type Required Inline Description
excludeTestRegex string

ExcludeTestRegex is used to exclude tests based on a regular expression.

includeTestRegex string

IncludeTestRegex is used to include tests based on a regular expression.

testFile string

TestFile is the name of the file containing the test to run. If no extension is provided, chainsaw will try with .yaml first and .yml if needed.

fullName bool

FullName makes use of the full test case folder path instead of the folder name.

ErrorOptions

Appears in:

ErrorOptions contains the global error configuration.

Field Type Required Inline Description
catch []CatchFinally

Catch defines what the tests steps will execute when an error happens. This will be combined with catch handlers defined at the test and step levels.

ExecutionOptions

Appears in:

ExecutionOptions determines how tests are run.

Field Type Required Inline Description
failFast bool

FailFast determines whether the test should stop upon encountering the first failure.

parallel int

The maximum number of tests to run at once.

repeatCount int

RepeatCount indicates how many times the tests should be executed.

forceTerminationGracePeriod meta/v1.Duration

ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.

NamespaceOptions

Appears in:

NamespaceOptions contains the configuration used to allocate a namespace for each test.

Field Type Required Inline Description
name string

Name defines the namespace to use for tests. If not specified, every test will execute in a random ephemeral namespace unless the namespace is overridden in a the test spec.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

template Projection

Template defines a template to create the test namespace.

ReportFormatType

(Alias of string)

Appears in:

ReportOptions

Appears in:

ReportOptions contains the configuration used for reporting.

Field Type Required Inline Description
format ReportFormatType

ReportFormat determines test report format (JSON

path string

ReportPath defines the path.

name string

ReportName defines the name of report to create. It defaults to "chainsaw-report".

TemplatingOptions

Appears in:

TemplatingOptions contains the templating configuration.

Field Type Required Inline Description
enabled bool

Enabled determines whether resources should be considered for templating.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

\ No newline at end of file + chainsaw (v1alpha2) - Chainsaw
Skip to content

v1alpha2

Package v1alpha2 contains API Schema definitions for the v1alpha2 API group.

Resource Types

Configuration

Configuration is the resource that contains the configuration used to run tests.

Field Type Required Inline Description
apiVersion string ✅ chainsaw.kyverno.io/v1alpha2
kind string ✅ Configuration
metadata meta/v1.ObjectMeta

Standard object's metadata.

spec ConfigurationSpec ✅

Configuration spec.

CleanupOptions

Appears in:

CleanupOptions contains the configuration used for cleaning up resources.

Field Type Required Inline Description
skipDelete bool

If set, do not delete the resources after running a test.

delayBeforeCleanup meta/v1.Duration

DelayBeforeCleanup adds a delay between the time a test ends and the time cleanup starts.

ConfigurationSpec

Appears in:

ConfigurationSpec contains the configuration used to run tests.

Field Type Required Inline Description
cleanup CleanupOptions

Cleanup contains cleanup configuration.

clusters Clusters

Clusters holds a registry to clusters to support multi-cluster tests.

deletion DeletionOptions

Deletion contains the global deletion configuration.

discovery DiscoveryOptions

Discovery contains tests discovery configuration.

error ErrorOptions

Error contains the global error configuration.

execution ExecutionOptions

Execution contains tests execution configuration.

namespace NamespaceOptions

Namespace contains properties for the namespace to use for tests.

report ReportOptions

Report contains properties for the report.

templating TemplatingOptions

Templating contains the templating config.

timeouts DefaultTimeouts

Global timeouts configuration. Applies to all tests/test steps if not overridden.

DeletionOptions

Appears in:

DeletionOptions contains the configuration used for deleting resources.

Field Type Required Inline Description
propagation meta/v1.DeletionPropagation

Propagation decides if a deletion will propagate to the dependents of the object, and how the garbage collector will handle the propagation.

DiscoveryOptions

Appears in:

DiscoveryOptions contains the discovery configuration used when discovering tests in folders.

Field Type Required Inline Description
excludeTestRegex string

ExcludeTestRegex is used to exclude tests based on a regular expression.

includeTestRegex string

IncludeTestRegex is used to include tests based on a regular expression.

testFile string

TestFile is the name of the file containing the test to run. If no extension is provided, chainsaw will try with .yaml first and .yml if needed.

fullName bool

FullName makes use of the full test case folder path instead of the folder name.

ErrorOptions

Appears in:

ErrorOptions contains the global error configuration.

Field Type Required Inline Description
catch []CatchFinally

Catch defines what the tests steps will execute when an error happens. This will be combined with catch handlers defined at the test and step levels.

ExecutionOptions

Appears in:

ExecutionOptions determines how tests are run.

Field Type Required Inline Description
failFast bool

FailFast determines whether the test should stop upon encountering the first failure.

parallel int

The maximum number of tests to run at once.

repeatCount int

RepeatCount indicates how many times the tests should be executed.

forceTerminationGracePeriod meta/v1.Duration

ForceTerminationGracePeriod forces the termination grace period on pods, statefulsets, daemonsets and deployments.

NamespaceOptions

Appears in:

NamespaceOptions contains the configuration used to allocate a namespace for each test.

Field Type Required Inline Description
name string

Name defines the namespace to use for tests. If not specified, every test will execute in a random ephemeral namespace unless the namespace is overridden in a the test spec.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

template Projection

Template defines a template to create the test namespace.

ReportFormatType

(Alias of string)

Appears in:

ReportOptions

Appears in:

ReportOptions contains the configuration used for reporting.

Field Type Required Inline Description
format ReportFormatType

ReportFormat determines test report format (JSON

path string

ReportPath defines the path.

name string

ReportName defines the name of report to create. It defaults to "chainsaw-report".

TemplatingOptions

Appears in:

TemplatingOptions contains the templating configuration.

Field Type Required Inline Description
enabled bool

Enabled determines whether resources should be considered for templating.

compiler policy/v1alpha1.Compiler

Compiler defines the default compiler to use when evaluating expressions.

\ No newline at end of file diff --git a/main/reference/builtins/index.html b/main/reference/builtins/index.html index 70df539e3..e2358016a 100644 --- a/main/reference/builtins/index.html +++ b/main/reference/builtins/index.html @@ -1 +1 @@ - Built-in bindings - Chainsaw
Skip to content

Built-in bindings

Chainsaw provides built-in bindings listed below.

Common

Name Purpose Type
$values Values provided when invoking chainsaw with --values flag any
$namespace Name of the current test namespace string
$client Kubernetes client chainsaw is connected to (if not running with --no-cluster) object
$config Kubernetes client config chainsaw is connected to (if not running with --no-cluster) object

In tests

Name Purpose Type
$test.id Current test id int
$test.metadata Current test metadata metav1.ObjectMeta

Note

  • $test.id starts at 1 for the first test

In steps

Name Purpose Type
$step.id Current step id int

Note

  • $step.id starts at 1 for the first step

In operations

Name Purpose Type
$operation.id Current operation id int
$operation.resourceId Current resource id int

Note

  • $operation.id starts at 1 for the first operation
  • $operation.resourceId maps to the resource id (starting at 1) in case the operation loads a file that contains multiple resources (the same operation is repeated once per resource)

In checks and outputs

Name Purpose Type
@ The state of the resource (if any) at the end of the operation any
$error The error message (if any) at the end of the operation string
$stdout The content of the standard console output (if any) at the end of the operation string
$stderr The content of the standard console error output (if any) at the end of the operation string

Note

  • $stdout and $stderr are only available in script and command operations
\ No newline at end of file + Built-in bindings - Chainsaw
Skip to content

Built-in bindings

Chainsaw provides built-in bindings listed below.

Common

Name Purpose Type
$values Values provided when invoking chainsaw with --values flag any
$namespace Name of the current test namespace string
$client Kubernetes client chainsaw is connected to (if not running with --no-cluster) object
$config Kubernetes client config chainsaw is connected to (if not running with --no-cluster) object

In tests

Name Purpose Type
$test.id Current test id int
$test.metadata Current test metadata metav1.ObjectMeta

Note

  • $test.id starts at 1 for the first test

In steps

Name Purpose Type
$step.id Current step id int

Note

  • $step.id starts at 1 for the first step

In operations

Name Purpose Type
$operation.id Current operation id int
$operation.resourceId Current resource id int

Note

  • $operation.id starts at 1 for the first operation
  • $operation.resourceId maps to the resource id (starting at 1) in case the operation loads a file that contains multiple resources (the same operation is repeated once per resource)

In checks and outputs

Name Purpose Type
@ The state of the resource (if any) at the end of the operation any
$error The error message (if any) at the end of the operation string
$stdout The content of the standard console output (if any) at the end of the operation string
$stderr The content of the standard console error output (if any) at the end of the operation string

Note

  • $stdout and $stderr are only available in script and command operations
\ No newline at end of file diff --git a/main/reference/commands/chainsaw/index.html b/main/reference/commands/chainsaw/index.html index 7da51d73e..634352c44 100644 --- a/main/reference/commands/chainsaw/index.html +++ b/main/reference/commands/chainsaw/index.html @@ -1,3 +1,3 @@ - chainsaw - Chainsaw
Skip to content

chainsaw

chainsaw

Stronger tool for e2e testing

chainsaw [flags]
+ chainsaw - Chainsaw      

chainsaw

chainsaw

Stronger tool for e2e testing

chainsaw [flags]
 

Options

  -h, --help   help for chainsaw
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_assert/index.html b/main/reference/commands/chainsaw_assert/index.html index b88692163..4e59dbe5a 100644 --- a/main/reference/commands/chainsaw_assert/index.html +++ b/main/reference/commands/chainsaw_assert/index.html @@ -1,4 +1,4 @@ - chainsaw assert - Chainsaw
Skip to content

chainsaw assert

chainsaw assert

Evaluate assertion

chainsaw assert [flags] [FILE]
+ chainsaw assert - Chainsaw      

chainsaw assert

chainsaw assert

Evaluate assertion

chainsaw assert [flags] [FILE]
 

Options

      --clustered                           Defines if the resource is clustered (only applies when resource is loaded from a file)
   -f, --file string                         Path to the file to assert or '-' to read from stdin
   -h, --help                                help for assert
@@ -25,4 +25,4 @@
       --no-color                            Removes output colors
   -r, --resource string                     Path to the file containing the resource
       --timeout duration                    The assert timeout to use (default 30s)
-

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file +

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file diff --git a/main/reference/commands/chainsaw_build/index.html b/main/reference/commands/chainsaw_build/index.html index 640df14c5..ca1704675 100644 --- a/main/reference/commands/chainsaw_build/index.html +++ b/main/reference/commands/chainsaw_build/index.html @@ -1,3 +1,3 @@ - chainsaw build - Chainsaw
Skip to content

chainsaw build

chainsaw build

Build commands

chainsaw build [flags]
+ chainsaw build - Chainsaw      

chainsaw build

chainsaw build

Build commands

chainsaw build [flags]
 

Options

  -h, --help   help for build
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_build_docs/index.html b/main/reference/commands/chainsaw_build_docs/index.html index abacba551..fd7390760 100644 --- a/main/reference/commands/chainsaw_build_docs/index.html +++ b/main/reference/commands/chainsaw_build_docs/index.html @@ -1,7 +1,7 @@ - chainsaw build docs - Chainsaw
Skip to content

chainsaw build docs

chainsaw build docs

Build tests documentation

chainsaw build docs [flags]
+ chainsaw build docs - Chainsaw      

chainsaw build docs

chainsaw build docs

Build tests documentation

chainsaw build docs [flags]
 

Options

      --catalog string         Path to the built test catalog file
   -h, --help                   help for docs
       --readme-file string     Name of the built docs file (default "README.md")
       --test-dir stringArray   Directories containing test cases to run
       --test-file string       Name of the test file (default "chainsaw-test")
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_completion/index.html b/main/reference/commands/chainsaw_completion/index.html index 8ce3f0ee1..73d47f900 100644 --- a/main/reference/commands/chainsaw_completion/index.html +++ b/main/reference/commands/chainsaw_completion/index.html @@ -1,2 +1,2 @@ - chainsaw completion - Chainsaw
Skip to content

chainsaw completion

chainsaw completion

Generate the autocompletion script for the specified shell

Synopsis

Generate the autocompletion script for chainsaw for the specified shell. See each sub-command's help for details on how to use the generated script.

Options

  -h, --help   help for completion
-

SEE ALSO

\ No newline at end of file + chainsaw completion - Chainsaw
Skip to content

chainsaw completion

chainsaw completion

Generate the autocompletion script for the specified shell

Synopsis

Generate the autocompletion script for chainsaw for the specified shell. See each sub-command's help for details on how to use the generated script.

Options

  -h, --help   help for completion
+

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_completion_bash/index.html b/main/reference/commands/chainsaw_completion_bash/index.html index 67fd751e7..87a755f33 100644 --- a/main/reference/commands/chainsaw_completion_bash/index.html +++ b/main/reference/commands/chainsaw_completion_bash/index.html @@ -1,7 +1,7 @@ - chainsaw completion bash - Chainsaw
Skip to content

chainsaw completion bash

chainsaw completion bash

Generate the autocompletion script for bash

Synopsis

Generate the autocompletion script for the bash shell.

This script depends on the 'bash-completion' package. If it is not installed already, you can install it via your OS's package manager.

To load completions in your current shell session:

source <(chainsaw completion bash)
+ chainsaw completion bash - Chainsaw      

chainsaw completion bash

chainsaw completion bash

Generate the autocompletion script for bash

Synopsis

Generate the autocompletion script for the bash shell.

This script depends on the 'bash-completion' package. If it is not installed already, you can install it via your OS's package manager.

To load completions in your current shell session:

source <(chainsaw completion bash)
 

To load completions for every new session, execute once:

Linux:

chainsaw completion bash > /etc/bash_completion.d/chainsaw
 

macOS:

chainsaw completion bash > $(brew --prefix)/etc/bash_completion.d/chainsaw
 

You will need to start a new shell for this setup to take effect.

chainsaw completion bash
 

Options

  -h, --help              help for bash
       --no-descriptions   disable completion descriptions
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_completion_fish/index.html b/main/reference/commands/chainsaw_completion_fish/index.html index b4a762fe5..84f4db4e7 100644 --- a/main/reference/commands/chainsaw_completion_fish/index.html +++ b/main/reference/commands/chainsaw_completion_fish/index.html @@ -1,6 +1,6 @@ - chainsaw completion fish - Chainsaw
Skip to content

chainsaw completion fish

chainsaw completion fish

Generate the autocompletion script for fish

Synopsis

Generate the autocompletion script for the fish shell.

To load completions in your current shell session:

chainsaw completion fish | source
+ chainsaw completion fish - Chainsaw      

chainsaw completion fish

chainsaw completion fish

Generate the autocompletion script for fish

Synopsis

Generate the autocompletion script for the fish shell.

To load completions in your current shell session:

chainsaw completion fish | source
 

To load completions for every new session, execute once:

chainsaw completion fish > ~/.config/fish/completions/chainsaw.fish
 

You will need to start a new shell for this setup to take effect.

chainsaw completion fish [flags]
 

Options

  -h, --help              help for fish
       --no-descriptions   disable completion descriptions
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_completion_powershell/index.html b/main/reference/commands/chainsaw_completion_powershell/index.html index 7487017c1..8d9de48a8 100644 --- a/main/reference/commands/chainsaw_completion_powershell/index.html +++ b/main/reference/commands/chainsaw_completion_powershell/index.html @@ -1,5 +1,5 @@ - chainsaw completion powershell - Chainsaw
Skip to content

chainsaw completion powershell

chainsaw completion powershell

Generate the autocompletion script for powershell

Synopsis

Generate the autocompletion script for powershell.

To load completions in your current shell session:

chainsaw completion powershell | Out-String | Invoke-Expression
+ chainsaw completion powershell - Chainsaw      

chainsaw completion powershell

chainsaw completion powershell

Generate the autocompletion script for powershell

Synopsis

Generate the autocompletion script for powershell.

To load completions in your current shell session:

chainsaw completion powershell | Out-String | Invoke-Expression
 

To load completions for every new session, add the output of the above command to your powershell profile.

chainsaw completion powershell [flags]
 

Options

  -h, --help              help for powershell
       --no-descriptions   disable completion descriptions
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_completion_zsh/index.html b/main/reference/commands/chainsaw_completion_zsh/index.html index 122e203ce..ba62449fa 100644 --- a/main/reference/commands/chainsaw_completion_zsh/index.html +++ b/main/reference/commands/chainsaw_completion_zsh/index.html @@ -1,8 +1,8 @@ - chainsaw completion zsh - Chainsaw
Skip to content

chainsaw completion zsh

chainsaw completion zsh

Generate the autocompletion script for zsh

Synopsis

Generate the autocompletion script for the zsh shell.

If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once:

echo "autoload -U compinit; compinit" >> ~/.zshrc
+ chainsaw completion zsh - Chainsaw      

chainsaw completion zsh

chainsaw completion zsh

Generate the autocompletion script for zsh

Synopsis

Generate the autocompletion script for the zsh shell.

If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once:

echo "autoload -U compinit; compinit" >> ~/.zshrc
 

To load completions in your current shell session:

source <(chainsaw completion zsh)
 

To load completions for every new session, execute once:

Linux:

chainsaw completion zsh > "${fpath[1]}/_chainsaw"
 

macOS:

chainsaw completion zsh > $(brew --prefix)/share/zsh/site-functions/_chainsaw
 

You will need to start a new shell for this setup to take effect.

chainsaw completion zsh [flags]
 

Options

  -h, --help              help for zsh
       --no-descriptions   disable completion descriptions
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_create/index.html b/main/reference/commands/chainsaw_create/index.html index d03f9b8f2..af2bf6200 100644 --- a/main/reference/commands/chainsaw_create/index.html +++ b/main/reference/commands/chainsaw_create/index.html @@ -1,3 +1,3 @@ - chainsaw create - Chainsaw
Skip to content

chainsaw create

chainsaw create

Create Chainsaw resources

chainsaw create [flags]
+ chainsaw create - Chainsaw      

chainsaw create

chainsaw create

Create Chainsaw resources

chainsaw create [flags]
 

Options

  -h, --help   help for create
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_create_test/index.html b/main/reference/commands/chainsaw_create_test/index.html index cef6327e8..3e6f994a0 100644 --- a/main/reference/commands/chainsaw_create_test/index.html +++ b/main/reference/commands/chainsaw_create_test/index.html @@ -1,6 +1,6 @@ - chainsaw create test - Chainsaw
Skip to content

chainsaw create test

chainsaw create test

Create a Chainsaw test

chainsaw create test [flags]
+ chainsaw create test - Chainsaw      

chainsaw create test

chainsaw create test

Create a Chainsaw test

chainsaw create test [flags]
 

Options

      --description   If set, adds description when applicable (default true)
       --force         If set, existing test will be deleted if needed
   -h, --help          help for test
       --save          If set, created test will be saved
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_docs/index.html b/main/reference/commands/chainsaw_docs/index.html index 3af866a52..33a4ad29a 100644 --- a/main/reference/commands/chainsaw_docs/index.html +++ b/main/reference/commands/chainsaw_docs/index.html @@ -1,6 +1,6 @@ - chainsaw docs - Chainsaw
Skip to content

chainsaw docs

chainsaw docs

Generate reference documentation

chainsaw docs [flags]
+ chainsaw docs - Chainsaw      

chainsaw docs

chainsaw docs

Generate reference documentation

chainsaw docs [flags]
 

Options

      --autogenTag      Determines if the generated docs should contain a timestamp (default true)
   -h, --help            help for docs
   -o, --output string   Output path (default ".")
       --website         Website version
-

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file +

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file diff --git a/main/reference/commands/chainsaw_export/index.html b/main/reference/commands/chainsaw_export/index.html index 78e64d3e4..26ec5550b 100644 --- a/main/reference/commands/chainsaw_export/index.html +++ b/main/reference/commands/chainsaw_export/index.html @@ -1,3 +1,3 @@ - chainsaw export - Chainsaw
Skip to content

chainsaw export

chainsaw export

Export commands

chainsaw export [flags]
+ chainsaw export - Chainsaw      

chainsaw export

chainsaw export

Export commands

chainsaw export [flags]
 

Options

  -h, --help   help for export
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_export_schemas/index.html b/main/reference/commands/chainsaw_export_schemas/index.html index 8d24e84d8..8685e15b4 100644 --- a/main/reference/commands/chainsaw_export_schemas/index.html +++ b/main/reference/commands/chainsaw_export_schemas/index.html @@ -1,3 +1,3 @@ - chainsaw export schemas - Chainsaw
Skip to content

chainsaw export schemas

chainsaw export schemas

Export JSON schemas

chainsaw export schemas [flags]
+ chainsaw export schemas - Chainsaw      

chainsaw export schemas

chainsaw export schemas

Export JSON schemas

chainsaw export schemas [flags]
 

Options

  -h, --help   help for schemas
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_lint/index.html b/main/reference/commands/chainsaw_lint/index.html index 743556c3b..e365e9d02 100644 --- a/main/reference/commands/chainsaw_lint/index.html +++ b/main/reference/commands/chainsaw_lint/index.html @@ -1,4 +1,4 @@ - chainsaw lint - Chainsaw
Skip to content

chainsaw lint

chainsaw lint

Lint a file or read from standard input

Synopsis

Use chainsaw lint to lint a specific file or read from standard input for either test or configuration.

chainsaw lint [test|configuration] [flags]
+ chainsaw lint - Chainsaw      

chainsaw lint

chainsaw lint

Lint a file or read from standard input

Synopsis

Use chainsaw lint to lint a specific file or read from standard input for either test or configuration.

chainsaw lint [test|configuration] [flags]
 

Options

  -f, --file string   Specify the file to lint or '-' for standard input
   -h, --help          help for lint
-

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file +

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file diff --git a/main/reference/commands/chainsaw_migrate/index.html b/main/reference/commands/chainsaw_migrate/index.html index ec74e95b8..f07b9e28a 100644 --- a/main/reference/commands/chainsaw_migrate/index.html +++ b/main/reference/commands/chainsaw_migrate/index.html @@ -1,3 +1,3 @@ - chainsaw migrate - Chainsaw
Skip to content

chainsaw migrate

chainsaw migrate

Migrate resources to Chainsaw

chainsaw migrate [flags]
+ chainsaw migrate - Chainsaw      

chainsaw migrate

chainsaw migrate

Migrate resources to Chainsaw

chainsaw migrate [flags]
 

Options

  -h, --help   help for migrate
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_migrate_kuttl/index.html b/main/reference/commands/chainsaw_migrate_kuttl/index.html index e19ea18d3..7f0db9493 100644 --- a/main/reference/commands/chainsaw_migrate_kuttl/index.html +++ b/main/reference/commands/chainsaw_migrate_kuttl/index.html @@ -1,3 +1,3 @@ - chainsaw migrate kuttl - Chainsaw
Skip to content

chainsaw migrate kuttl

chainsaw migrate kuttl

Migrate KUTTL resources to Chainsaw

chainsaw migrate kuttl [flags]
+ chainsaw migrate kuttl - Chainsaw      
\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_migrate_kuttl_config/index.html b/main/reference/commands/chainsaw_migrate_kuttl_config/index.html index dd9c4219b..6debc48f1 100644 --- a/main/reference/commands/chainsaw_migrate_kuttl_config/index.html +++ b/main/reference/commands/chainsaw_migrate_kuttl_config/index.html @@ -1,5 +1,5 @@ - chainsaw migrate kuttl config - Chainsaw
Skip to content

chainsaw migrate kuttl config

chainsaw migrate kuttl config

Migrate KUTTL config to Chainsaw

chainsaw migrate kuttl config [flags]
+ chainsaw migrate kuttl config - Chainsaw      

chainsaw migrate kuttl config

chainsaw migrate kuttl config

Migrate KUTTL config to Chainsaw

chainsaw migrate kuttl config [flags]
 

Options

      --cleanup   If set, delete converted files
   -h, --help      help for config
       --save      If set, converted files will be saved
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_migrate_kuttl_tests/index.html b/main/reference/commands/chainsaw_migrate_kuttl_tests/index.html index 4f1e8368f..ca5594551 100644 --- a/main/reference/commands/chainsaw_migrate_kuttl_tests/index.html +++ b/main/reference/commands/chainsaw_migrate_kuttl_tests/index.html @@ -1,5 +1,5 @@ - chainsaw migrate kuttl tests - Chainsaw
Skip to content

chainsaw migrate kuttl tests

chainsaw migrate kuttl tests

Migrate KUTTL tests to Chainsaw

chainsaw migrate kuttl tests [flags]
+ chainsaw migrate kuttl tests - Chainsaw      

chainsaw migrate kuttl tests

chainsaw migrate kuttl tests

Migrate KUTTL tests to Chainsaw

chainsaw migrate kuttl tests [flags]
 

Options

      --cleanup   If set, delete converted files
   -h, --help      help for tests
       --save      If set, converted files will be saved
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_renovate/index.html b/main/reference/commands/chainsaw_renovate/index.html index 0c6dba35c..cabd33980 100644 --- a/main/reference/commands/chainsaw_renovate/index.html +++ b/main/reference/commands/chainsaw_renovate/index.html @@ -1,3 +1,3 @@ - chainsaw renovate - Chainsaw
Skip to content

chainsaw renovate

chainsaw renovate

Upgrade Chainsaw resources

chainsaw renovate [flags]
+ chainsaw renovate - Chainsaw      

chainsaw renovate

chainsaw renovate

Upgrade Chainsaw resources

chainsaw renovate [flags]
 

Options

  -h, --help   help for renovate
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_renovate_config/index.html b/main/reference/commands/chainsaw_renovate_config/index.html index 49e3d555c..4763edf6e 100644 --- a/main/reference/commands/chainsaw_renovate_config/index.html +++ b/main/reference/commands/chainsaw_renovate_config/index.html @@ -1,4 +1,4 @@ - chainsaw renovate config - Chainsaw
Skip to content

chainsaw renovate config

chainsaw renovate config

Upgrade Chainsaw configuration to the latest version

chainsaw renovate config [flags]
+ chainsaw renovate config - Chainsaw      

chainsaw renovate config

chainsaw renovate config

Upgrade Chainsaw configuration to the latest version

chainsaw renovate config [flags]
 

Options

  -h, --help   help for config
       --save   If set, converted files will be saved
-

SEE ALSO

\ No newline at end of file +

SEE ALSO

\ No newline at end of file diff --git a/main/reference/commands/chainsaw_test/index.html b/main/reference/commands/chainsaw_test/index.html index bc7b87831..2f80836a5 100644 --- a/main/reference/commands/chainsaw_test/index.html +++ b/main/reference/commands/chainsaw_test/index.html @@ -1,4 +1,4 @@ - chainsaw test - Chainsaw
Skip to content

chainsaw test

chainsaw test

Run tests

chainsaw test [flags]... [test directories]...
+ chainsaw test - Chainsaw      

chainsaw test

chainsaw test

Run tests

chainsaw test [flags]... [test directories]...
 

Options

      --apply-timeout duration                    The apply timeout to use as default for configuration (default 5s)
       --assert-timeout duration                   The assert timeout to use as default for configuration (default 30s)
       --cleanup-delay duration                    Adds a delay between the time a test ends and the time cleanup starts
@@ -53,4 +53,4 @@
       --test-dir strings                          Directories containing test cases to run
       --test-file string                          Name of the test file (default "chainsaw-test")
       --values strings                            Values passed to the tests
-

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file +

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file diff --git a/main/reference/commands/chainsaw_version/index.html b/main/reference/commands/chainsaw_version/index.html index 4e06cf690..bfa4e6db8 100644 --- a/main/reference/commands/chainsaw_version/index.html +++ b/main/reference/commands/chainsaw_version/index.html @@ -1,3 +1,3 @@ - chainsaw version - Chainsaw
Skip to content

chainsaw version

chainsaw version

Print the version informations

chainsaw version [flags]
+ chainsaw version - Chainsaw      

chainsaw version

chainsaw version

Print the version informations

chainsaw version [flags]
 

Options

  -h, --help   help for version
-

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file +

SEE ALSO

  • chainsaw - Stronger tool for e2e testing
\ No newline at end of file diff --git a/main/reference/index.html b/main/reference/index.html index cc7f7c258..34aaaed87 100644 --- a/main/reference/index.html +++ b/main/reference/index.html @@ -1 +1 @@ - Reference documentation - Chainsaw
Skip to content

Reference documentation

Info

Select an item in the navigation menu to browse a specific page.

\ No newline at end of file + Reference documentation - Chainsaw
Skip to content

Reference documentation

Info

Select an item in the navigation menu to browse a specific page.

\ No newline at end of file diff --git a/main/reference/jp/examples/abs/index.html b/main/reference/jp/examples/abs/index.html index 8176fc768..b1e5fcb19 100644 --- a/main/reference/jp/examples/abs/index.html +++ b/main/reference/jp/examples/abs/index.html @@ -1,2 +1,2 @@ - abs - Chainsaw
Skip to content

abs

Signature

abs(number)

Description

Returns the absolute value of the provided argument.

Examples

abs(`-1`) == `1`
-
\ No newline at end of file + abs - Chainsaw
Skip to content

abs

Signature

abs(number)

Description

Returns the absolute value of the provided argument.

Examples

abs(`-1`) == `1`
+
\ No newline at end of file diff --git a/main/reference/jp/examples/add/index.html b/main/reference/jp/examples/add/index.html index 920b14878..01403d76e 100644 --- a/main/reference/jp/examples/add/index.html +++ b/main/reference/jp/examples/add/index.html @@ -1 +1 @@ - add - Chainsaw
Skip to content

add

Signature

add(any, any)

Description

Does arithmetic addition of two specified values of numbers, quantities, and durations.

Examples

TODO

\ No newline at end of file + add - Chainsaw
Skip to content

add

Signature

add(any, any)

Description

Does arithmetic addition of two specified values of numbers, quantities, and durations.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/as_string/index.html b/main/reference/jp/examples/as_string/index.html index 05975f1de..c73de2786 100644 --- a/main/reference/jp/examples/as_string/index.html +++ b/main/reference/jp/examples/as_string/index.html @@ -1,2 +1,2 @@ - as_string - Chainsaw
Skip to content

as_string

Signature

as_string(any)

Description

Returns the passed in argument converted into a string.

Examples

as_string('foobar') == 'foobar'
-
\ No newline at end of file + as_string - Chainsaw
Skip to content

as_string

Signature

as_string(any)

Description

Returns the passed in argument converted into a string.

Examples

as_string('foobar') == 'foobar'
+
\ No newline at end of file diff --git a/main/reference/jp/examples/at/index.html b/main/reference/jp/examples/at/index.html index 825260dcd..d93a8ddb3 100644 --- a/main/reference/jp/examples/at/index.html +++ b/main/reference/jp/examples/at/index.html @@ -1,2 +1,2 @@ - at - Chainsaw
Skip to content

at

Signature

at(array, number)

Description

Returns the element in an array at the given index.

Examples

at([`10`,`15`,`20`], `1`) == `15`
-
\ No newline at end of file + at - Chainsaw
Skip to content

at

Signature

at(array, number)

Description

Returns the element in an array at the given index.

Examples

at([`10`,`15`,`20`], `1`) == `15`
+
\ No newline at end of file diff --git a/main/reference/jp/examples/avg/index.html b/main/reference/jp/examples/avg/index.html index 89dc2ba9a..1d37fb82a 100644 --- a/main/reference/jp/examples/avg/index.html +++ b/main/reference/jp/examples/avg/index.html @@ -1,2 +1,2 @@ - avg - Chainsaw
Skip to content

avg

Signature

avg(array[number])

Description

Returns the average of the elements in the provided array. An empty array will produce a return value of null.

Examples

avg([`10`,`15`,`20`]) == `15`
-
\ No newline at end of file + avg - Chainsaw
Skip to content

avg

Signature

avg(array[number])

Description

Returns the average of the elements in the provided array. An empty array will produce a return value of null.

Examples

avg([`10`,`15`,`20`]) == `15`
+
\ No newline at end of file diff --git a/main/reference/jp/examples/base64_decode/index.html b/main/reference/jp/examples/base64_decode/index.html index 0dfb6b7dd..eca4221d1 100644 --- a/main/reference/jp/examples/base64_decode/index.html +++ b/main/reference/jp/examples/base64_decode/index.html @@ -1 +1 @@ - base64_decode - Chainsaw
Skip to content

base64_decode

Signature

base64_decode(string)

Description

Decodes a base 64 string.

Examples

TODO

\ No newline at end of file + base64_decode - Chainsaw
Skip to content

base64_decode

Signature

base64_decode(string)

Description

Decodes a base 64 string.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/base64_encode/index.html b/main/reference/jp/examples/base64_encode/index.html index a540ce328..90a525ecb 100644 --- a/main/reference/jp/examples/base64_encode/index.html +++ b/main/reference/jp/examples/base64_encode/index.html @@ -1 +1 @@ - base64_encode - Chainsaw
Skip to content

base64_encode

Signature

base64_encode(string)

Description

Encodes a regular, plaintext and unencoded string to base64.

Examples

TODO

\ No newline at end of file + base64_encode - Chainsaw
Skip to content

base64_encode

Signature

base64_encode(string)

Description

Encodes a regular, plaintext and unencoded string to base64.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/ceil/index.html b/main/reference/jp/examples/ceil/index.html index ec6d67c58..f6e86c5e2 100644 --- a/main/reference/jp/examples/ceil/index.html +++ b/main/reference/jp/examples/ceil/index.html @@ -1,2 +1,2 @@ - ceil - Chainsaw
Skip to content

ceil

Signature

ceil(number)

Description

Returns the next highest integer value by rounding up if necessary.

Examples

ceil(`1.9`) == `2`
-
\ No newline at end of file + ceil - Chainsaw
Skip to content

ceil

Signature

ceil(number)

Description

Returns the next highest integer value by rounding up if necessary.

Examples

ceil(`1.9`) == `2`
+
\ No newline at end of file diff --git a/main/reference/jp/examples/compare/index.html b/main/reference/jp/examples/compare/index.html index 6fbbaca03..bc86f9769 100644 --- a/main/reference/jp/examples/compare/index.html +++ b/main/reference/jp/examples/compare/index.html @@ -1 +1 @@ - compare - Chainsaw
Skip to content

compare

Signature

compare(string, string)

Description

Compares two strings lexicographically.

Examples

TODO

\ No newline at end of file + compare - Chainsaw
Skip to content

compare

Signature

compare(string, string)

Description

Compares two strings lexicographically.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/concat/index.html b/main/reference/jp/examples/concat/index.html index 57295d4f0..6b7fae875 100644 --- a/main/reference/jp/examples/concat/index.html +++ b/main/reference/jp/examples/concat/index.html @@ -1,2 +1,2 @@ - concat - Chainsaw
Skip to content

concat

Signature

concat(string, string)

Description

Concatenates two strings together and returns the result.

Examples

concat('foo', 'bar') == 'foobar'
-
\ No newline at end of file + concat - Chainsaw
Skip to content

concat

Signature

concat(string, string)

Description

Concatenates two strings together and returns the result.

Examples

concat('foo', 'bar') == 'foobar'
+
\ No newline at end of file diff --git a/main/reference/jp/examples/contains/index.html b/main/reference/jp/examples/contains/index.html index c5405192c..6c46d4270 100644 --- a/main/reference/jp/examples/contains/index.html +++ b/main/reference/jp/examples/contains/index.html @@ -1,5 +1,5 @@ - contains - Chainsaw
Skip to content

contains

Signature

contains(array|string, any)

Description

Returns true if the given subject contains the provided search value. If the subject is an array, this function returns true if one of the elements in the array is equal to the provided search value. If the provided subject is a string, this function returns true if the string contains the provided search argument.

Examples

With strings

contains('foobar', 'bar') == `true`
+ contains - Chainsaw      

contains

Signature

contains(array|string, any)

Description

Returns true if the given subject contains the provided search value. If the subject is an array, this function returns true if one of the elements in the array is equal to the provided search value. If the provided subject is a string, this function returns true if the string contains the provided search argument.

Examples

With strings

contains('foobar', 'bar') == `true`
 
contains('foobar', 'not') == `false`
 

With arrays

contains(['foo', 'bar'], 'bar') == `true`
 
contains(['foo', 'bar'], 'not') == `true`
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/divide/index.html b/main/reference/jp/examples/divide/index.html index d9147b587..fe5678ad2 100644 --- a/main/reference/jp/examples/divide/index.html +++ b/main/reference/jp/examples/divide/index.html @@ -1 +1 @@ - divide - Chainsaw
Skip to content

divide

Signature

divide(any, any)

Description

Divisor must be non zero.

Examples

TODO

\ No newline at end of file + divide - Chainsaw
Skip to content

divide

Signature

divide(any, any)

Description

Divisor must be non zero.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/ends_with/index.html b/main/reference/jp/examples/ends_with/index.html index e7e5da252..6d51fee9e 100644 --- a/main/reference/jp/examples/ends_with/index.html +++ b/main/reference/jp/examples/ends_with/index.html @@ -1,3 +1,3 @@ - ends_with - Chainsaw
Skip to content

ends_with

Signature

ends_with(string, string)

Description

Reports whether the given string ends with the provided suffix argument.

Examples

ends_with('foobar', 'bar') == `true`
+ ends_with - Chainsaw      

ends_with

Signature

ends_with(string, string)

Description

Reports whether the given string ends with the provided suffix argument.

Examples

ends_with('foobar', 'bar') == `true`
 
ends_with('foobar', 'foo') == `false`
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/env/index.html b/main/reference/jp/examples/env/index.html index 8b1711ea6..e6b698a0f 100644 --- a/main/reference/jp/examples/env/index.html +++ b/main/reference/jp/examples/env/index.html @@ -1,2 +1,2 @@ - env - Chainsaw
Skip to content

env

Signature

env(string)

Description

Returns the value of the environment variable passed in argument.

Examples

env('MY_ENV_VAR') == 'foo'
-
\ No newline at end of file + env - Chainsaw
Skip to content

env

Signature

env(string)

Description

Returns the value of the environment variable passed in argument.

Examples

env('MY_ENV_VAR') == 'foo'
+
\ No newline at end of file diff --git a/main/reference/jp/examples/equal_fold/index.html b/main/reference/jp/examples/equal_fold/index.html index c7ee13cb7..f5415143f 100644 --- a/main/reference/jp/examples/equal_fold/index.html +++ b/main/reference/jp/examples/equal_fold/index.html @@ -1 +1 @@ - equal_fold - Chainsaw
Skip to content

equal_fold

Signature

equal_fold(string, string)

Description

Allows comparing two strings for equivalency where the only differences are letter cases.

Examples

TODO

\ No newline at end of file + equal_fold - Chainsaw
Skip to content

equal_fold

Signature

equal_fold(string, string)

Description

Allows comparing two strings for equivalency where the only differences are letter cases.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/find_first/index.html b/main/reference/jp/examples/find_first/index.html index cea7f55bf..a9ad1e0f5 100644 --- a/main/reference/jp/examples/find_first/index.html +++ b/main/reference/jp/examples/find_first/index.html @@ -1,6 +1,6 @@ - find_first - Chainsaw
Skip to content

find_first

Signature

find_first(string, string, number, number)

Description

Returns the zero-based index of the first occurence where the substring appears in a string or null if it does not appear.

Examples

find_first('subject string', 'string', `0`) == `8`
+ find_first - Chainsaw      

find_first

Signature

find_first(string, string, number, number)

Description

Returns the zero-based index of the first occurence where the substring appears in a string or null if it does not appear.

Examples

find_first('subject string', 'string', `0`) == `8`
 
find_first('subject string', 'string', `8`) == `8`
 
find_first('subject string', 'string', `9`) == null
 
find_first('subject string', 'string', `0`, `14`) == `8`
 
find_first('subject string', 'string', `0`, `13`) == null
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/find_last/index.html b/main/reference/jp/examples/find_last/index.html index a4eb3e3f0..4858c85ab 100644 --- a/main/reference/jp/examples/find_last/index.html +++ b/main/reference/jp/examples/find_last/index.html @@ -1,6 +1,6 @@ - find_last - Chainsaw
Skip to content

find_last

Signature

find_last(string, string, number, number)

Description

Returns the zero-based index of the last occurence where the substring appears in a string or null if it does not appear.

Examples

find_last('subject string', 'string', `0`) == `8`
+ find_last - Chainsaw      

find_last

Signature

find_last(string, string, number, number)

Description

Returns the zero-based index of the last occurence where the substring appears in a string or null if it does not appear.

Examples

find_last('subject string', 'string', `0`) == `8`
 
find_last('subject string', 'string', `8`) == `8`
 
find_last('subject string', 'string', `9`) == null
 
find_last('subject string', 'string', `0`, `14`) == `8`
 
find_last('subject string', 'string', `0`, `13`) == null
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/floor/index.html b/main/reference/jp/examples/floor/index.html index 763ddeba5..d55259c52 100644 --- a/main/reference/jp/examples/floor/index.html +++ b/main/reference/jp/examples/floor/index.html @@ -1,2 +1,2 @@ - floor - Chainsaw
Skip to content

floor

Signature

floor(number)

Description

Returns the next lowest integer value by rounding down if necessary.

Examples

floor(`1.9`) == `1`
-
\ No newline at end of file + floor - Chainsaw
Skip to content

floor

Signature

floor(number)

Description

Returns the next lowest integer value by rounding down if necessary.

Examples

floor(`1.9`) == `1`
+
\ No newline at end of file diff --git a/main/reference/jp/examples/from_items/index.html b/main/reference/jp/examples/from_items/index.html index cb1160bd7..209a2cb95 100644 --- a/main/reference/jp/examples/from_items/index.html +++ b/main/reference/jp/examples/from_items/index.html @@ -1 +1 @@ - from_items - Chainsaw
Skip to content

from_items

Signature

from_items(array[array])

Description

Returns an object from the provided array of key value pairs. This function is the inversed of the items() function.

Examples

TODO

\ No newline at end of file + from_items - Chainsaw
Skip to content

from_items

Signature

from_items(array[array])

Description

Returns an object from the provided array of key value pairs. This function is the inversed of the items() function.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/group_by/index.html b/main/reference/jp/examples/group_by/index.html index 072e25029..875030859 100644 --- a/main/reference/jp/examples/group_by/index.html +++ b/main/reference/jp/examples/group_by/index.html @@ -1 +1 @@ - group_by - Chainsaw
Skip to content

group_by

Signature

group_by(array, expref)

Description

Groups an array of objects using an expression as the group key.

Examples

TODO

\ No newline at end of file + group_by - Chainsaw
Skip to content

group_by

Signature

group_by(array, expref)

Description

Groups an array of objects using an expression as the group key.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/items/index.html b/main/reference/jp/examples/items/index.html index e4ef3c66c..95b86df9f 100644 --- a/main/reference/jp/examples/items/index.html +++ b/main/reference/jp/examples/items/index.html @@ -1 +1 @@ - items - Chainsaw
Skip to content

items

Signature

items(object|array, string, string)

Description

Converts a map or array to an array of objects where each key:value is an item in the array.

Examples

TODO

\ No newline at end of file + items - Chainsaw
Skip to content

items

Signature

items(object|array, string, string)

Description

Converts a map or array to an array of objects where each key:value is an item in the array.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/join/index.html b/main/reference/jp/examples/join/index.html index f84829810..913051c5d 100644 --- a/main/reference/jp/examples/join/index.html +++ b/main/reference/jp/examples/join/index.html @@ -1 +1 @@ - join - Chainsaw
Skip to content

join

Signature

join(string, array[string])

Description

Returns all of the elements from the provided array joined together using the glue argument as a separator between each.

Examples

TODO

\ No newline at end of file + join - Chainsaw
Skip to content

join

Signature

join(string, array[string])

Description

Returns all of the elements from the provided array joined together using the glue argument as a separator between each.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/json_parse/index.html b/main/reference/jp/examples/json_parse/index.html index 5fddf8250..cd710bb01 100644 --- a/main/reference/jp/examples/json_parse/index.html +++ b/main/reference/jp/examples/json_parse/index.html @@ -1,2 +1,2 @@ - json_parse - Chainsaw
Skip to content

json_parse

Signature

json_parse(string)

Description

Parses a given JSON string into an object.

Examples

json_parse('{"foo":"bar"}') == { foo: 'bar' }
-
\ No newline at end of file + json_parse - Chainsaw
Skip to content

json_parse

Signature

json_parse(string)

Description

Parses a given JSON string into an object.

Examples

json_parse('{"foo":"bar"}') == { foo: 'bar' }
+
\ No newline at end of file diff --git a/main/reference/jp/examples/keys/index.html b/main/reference/jp/examples/keys/index.html index 3593d0eff..643436a16 100644 --- a/main/reference/jp/examples/keys/index.html +++ b/main/reference/jp/examples/keys/index.html @@ -1,2 +1,2 @@ - keys - Chainsaw
Skip to content

keys

Signature

keys(object)

Description

Returns an array containing the keys of the provided object.

Examples

keys({bar:'bam',foo:'baz'}) == ['bar','foo']
-
\ No newline at end of file + keys - Chainsaw
Skip to content

keys

Signature

keys(object)

Description

Returns an array containing the keys of the provided object.

Examples

keys({bar:'bam',foo:'baz'}) == ['bar','foo']
+
\ No newline at end of file diff --git a/main/reference/jp/examples/label_match/index.html b/main/reference/jp/examples/label_match/index.html index ea1868254..5cb09db78 100644 --- a/main/reference/jp/examples/label_match/index.html +++ b/main/reference/jp/examples/label_match/index.html @@ -1 +1 @@ - label_match - Chainsaw
Skip to content

label_match

Signature

label_match(object, object)

Description

Object arguments must be enclosed in backticks; ex. {{request.object.spec.template.metadata.labels}}.

Examples

TODO

\ No newline at end of file + label_match - Chainsaw
Skip to content

label_match

Signature

label_match(object, object)

Description

Object arguments must be enclosed in backticks; ex. {{request.object.spec.template.metadata.labels}}.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/length/index.html b/main/reference/jp/examples/length/index.html index f26a1b31e..c17e1dc8b 100644 --- a/main/reference/jp/examples/length/index.html +++ b/main/reference/jp/examples/length/index.html @@ -1,4 +1,4 @@ - length - Chainsaw
Skip to content

length

Signature

length(string|array|object)

Description

Returns the length of the given argument. If the argument is a string this function returns the number of code points in the string. If the argument is an array this function returns the number of elements in the array. If the argument is an object this function returns the number of key-value pairs in the object.

Examples

length([`10`,`15`,`20`]) == `3`
+ length - Chainsaw      

length

Signature

length(string|array|object)

Description

Returns the length of the given argument. If the argument is a string this function returns the number of code points in the string. If the argument is an array this function returns the number of elements in the array. If the argument is an object this function returns the number of key-value pairs in the object.

Examples

length([`10`,`15`,`20`]) == `3`
 
length([]) == `0`
 
length(null) -> error
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/lookup/index.html b/main/reference/jp/examples/lookup/index.html index 7d5804d45..c9d9ae496 100644 --- a/main/reference/jp/examples/lookup/index.html +++ b/main/reference/jp/examples/lookup/index.html @@ -1 +1 @@ - lookup - Chainsaw
Skip to content

lookup

Signature

lookup(object|array, string|number)

Description

Returns the value corresponding to the given key/index in the given object/array.

Examples

TODO

\ No newline at end of file + lookup - Chainsaw
Skip to content

lookup

Signature

lookup(object|array, string|number)

Description

Returns the value corresponding to the given key/index in the given object/array.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/lower/index.html b/main/reference/jp/examples/lower/index.html index 215fa3ace..a454bc5e7 100644 --- a/main/reference/jp/examples/lower/index.html +++ b/main/reference/jp/examples/lower/index.html @@ -1,2 +1,2 @@ - lower - Chainsaw
Skip to content

lower

Signature

lower(string)

Description

Returns the given string with all Unicode letters mapped to their lower case.

Examples

lower('FOOBAR') == 'foobar'
-
\ No newline at end of file + lower - Chainsaw
Skip to content

lower

Signature

lower(string)

Description

Returns the given string with all Unicode letters mapped to their lower case.

Examples

lower('FOOBAR') == 'foobar'
+
\ No newline at end of file diff --git a/main/reference/jp/examples/map/index.html b/main/reference/jp/examples/map/index.html index fa8ec86b0..e0de5acdd 100644 --- a/main/reference/jp/examples/map/index.html +++ b/main/reference/jp/examples/map/index.html @@ -1 +1 @@ - map - Chainsaw
Skip to content

map

Signature

map(expref, array)

Description

Transforms elements in a given array and returns the result.

Examples

TODO

\ No newline at end of file + map - Chainsaw
Skip to content

map

Signature

map(expref, array)

Description

Transforms elements in a given array and returns the result.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/max/index.html b/main/reference/jp/examples/max/index.html index 218669911..09b159360 100644 --- a/main/reference/jp/examples/max/index.html +++ b/main/reference/jp/examples/max/index.html @@ -1 +1 @@ - max - Chainsaw
Skip to content

max

Signature

max(array[number]|array[string])

Description

Returns the highest found element in the provided array argument. An empty array will produce a return value of null.

Examples

TODO

\ No newline at end of file + max - Chainsaw
Skip to content

max

Signature

max(array[number]|array[string])

Description

Returns the highest found element in the provided array argument. An empty array will produce a return value of null.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/max_by/index.html b/main/reference/jp/examples/max_by/index.html index d4ae338e5..297e3b545 100644 --- a/main/reference/jp/examples/max_by/index.html +++ b/main/reference/jp/examples/max_by/index.html @@ -1 +1 @@ - max_by - Chainsaw
Skip to content

max_by

Signature

max_by(array, expref)

Description

Returns the highest found element using a custom expression to compute the associated value for each element in the input array.

Examples

TODO

\ No newline at end of file + max_by - Chainsaw
Skip to content

max_by

Signature

max_by(array, expref)

Description

Returns the highest found element using a custom expression to compute the associated value for each element in the input array.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/merge/index.html b/main/reference/jp/examples/merge/index.html index b347cf456..a6a7ff53d 100644 --- a/main/reference/jp/examples/merge/index.html +++ b/main/reference/jp/examples/merge/index.html @@ -1 +1 @@ - merge - Chainsaw
Skip to content

merge

Signature

merge(object)

Description

Meges a list of objects together and returns the result.

Examples

TODO

\ No newline at end of file + merge - Chainsaw
Skip to content

merge

Signature

merge(object)

Description

Meges a list of objects together and returns the result.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/min/index.html b/main/reference/jp/examples/min/index.html index 8c55fa215..26fc0f7b3 100644 --- a/main/reference/jp/examples/min/index.html +++ b/main/reference/jp/examples/min/index.html @@ -1 +1 @@ - min - Chainsaw
Skip to content

min

Signature

min(array[number]|array[string])

Description

Returns the lowest found element in the provided array argument.

Examples

TODO

\ No newline at end of file + min - Chainsaw
Skip to content

min

Signature

min(array[number]|array[string])

Description

Returns the lowest found element in the provided array argument.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/min_by/index.html b/main/reference/jp/examples/min_by/index.html index 0c9997e1f..e63892301 100644 --- a/main/reference/jp/examples/min_by/index.html +++ b/main/reference/jp/examples/min_by/index.html @@ -1 +1 @@ - min_by - Chainsaw
Skip to content

min_by

Signature

min_by(array, expref)

Description

Returns the lowest found element using a custom expression to compute the associated value for each element in the input array.

Examples

TODO

\ No newline at end of file + min_by - Chainsaw
Skip to content

min_by

Signature

min_by(array, expref)

Description

Returns the lowest found element using a custom expression to compute the associated value for each element in the input array.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/modulo/index.html b/main/reference/jp/examples/modulo/index.html index 9a04b0b70..8c331950f 100644 --- a/main/reference/jp/examples/modulo/index.html +++ b/main/reference/jp/examples/modulo/index.html @@ -1 +1 @@ - modulo - Chainsaw
Skip to content

modulo

Signature

modulo(any, any)

Description

Divisor must be non-zero, arguments must be integers.

Examples

TODO

\ No newline at end of file + modulo - Chainsaw
Skip to content

modulo

Signature

modulo(any, any)

Description

Divisor must be non-zero, arguments must be integers.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/multiply/index.html b/main/reference/jp/examples/multiply/index.html index 89889afbf..d937cf7f5 100644 --- a/main/reference/jp/examples/multiply/index.html +++ b/main/reference/jp/examples/multiply/index.html @@ -1 +1 @@ - multiply - Chainsaw
Skip to content

multiply

Signature

multiply(any, any)

Description

Does arithmetic multiplication of two specified values of numbers, quantities, and durations.

Examples

TODO

\ No newline at end of file + multiply - Chainsaw
Skip to content

multiply

Signature

multiply(any, any)

Description

Does arithmetic multiplication of two specified values of numbers, quantities, and durations.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/not_null/index.html b/main/reference/jp/examples/not_null/index.html index 654eda351..487e5a599 100644 --- a/main/reference/jp/examples/not_null/index.html +++ b/main/reference/jp/examples/not_null/index.html @@ -1,3 +1,3 @@ - not_null - Chainsaw
Skip to content

not_null

Signature

not_null(any)

Description

Returns the first non null element in the input array.

Examples

not_null(null, null, 'foo') == 'foo'
+ not_null - Chainsaw      

not_null

Signature

not_null(any)

Description

Returns the first non null element in the input array.

Examples

not_null(null, null, 'foo') == 'foo'
 
not_null(null, null) == null
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/object_from_lists/index.html b/main/reference/jp/examples/object_from_lists/index.html index 3e1719c65..312a1f781 100644 --- a/main/reference/jp/examples/object_from_lists/index.html +++ b/main/reference/jp/examples/object_from_lists/index.html @@ -1 +1 @@ - object_from_lists - Chainsaw
Skip to content

object_from_lists

Signature

object_from_lists(array, array)

Description

Converts a pair of lists containing keys and values to an object.

Examples

TODO

\ No newline at end of file + object_from_lists - Chainsaw
Skip to content

object_from_lists

Signature

object_from_lists(array, array)

Description

Converts a pair of lists containing keys and values to an object.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/pad_left/index.html b/main/reference/jp/examples/pad_left/index.html index 09215b6d0..0fea80b92 100644 --- a/main/reference/jp/examples/pad_left/index.html +++ b/main/reference/jp/examples/pad_left/index.html @@ -1 +1 @@ - pad_left - Chainsaw
Skip to content

pad_left

Signature

pad_left(string, number, string)

Description

Adds characters to the beginning of a string.

Examples

TODO

\ No newline at end of file + pad_left - Chainsaw
Skip to content

pad_left

Signature

pad_left(string, number, string)

Description

Adds characters to the beginning of a string.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/pad_right/index.html b/main/reference/jp/examples/pad_right/index.html index 8ef706e89..67a50246f 100644 --- a/main/reference/jp/examples/pad_right/index.html +++ b/main/reference/jp/examples/pad_right/index.html @@ -1 +1 @@ - pad_right - Chainsaw
Skip to content

pad_right

Signature

pad_right(string, number, string)

Description

Adds characters to the end of a string.

Examples

TODO

\ No newline at end of file + pad_right - Chainsaw
Skip to content

pad_right

Signature

pad_right(string, number, string)

Description

Adds characters to the end of a string.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/parse_json/index.html b/main/reference/jp/examples/parse_json/index.html index 3393b4c43..774d02070 100644 --- a/main/reference/jp/examples/parse_json/index.html +++ b/main/reference/jp/examples/parse_json/index.html @@ -1 +1 @@ - parse_json - Chainsaw
Skip to content

parse_json

Signature

parse_json(string)

Description

Decodes a valid JSON encoded string to the appropriate type. Opposite of to_string function.

Examples

TODO

\ No newline at end of file + parse_json - Chainsaw
Skip to content

parse_json

Signature

parse_json(string)

Description

Decodes a valid JSON encoded string to the appropriate type. Opposite of to_string function.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/parse_yaml/index.html b/main/reference/jp/examples/parse_yaml/index.html index f9299aefd..c2ce6fd02 100644 --- a/main/reference/jp/examples/parse_yaml/index.html +++ b/main/reference/jp/examples/parse_yaml/index.html @@ -1 +1 @@ - parse_yaml - Chainsaw
Skip to content

parse_yaml

Signature

parse_yaml(string)

Description

Decodes a valid YAML encoded string to the appropriate type provided it can be represented as JSON.

Examples

TODO

\ No newline at end of file + parse_yaml - Chainsaw
Skip to content

parse_yaml

Signature

parse_yaml(string)

Description

Decodes a valid YAML encoded string to the appropriate type provided it can be represented as JSON.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/path_canonicalize/index.html b/main/reference/jp/examples/path_canonicalize/index.html index a7f04531b..db50c25ce 100644 --- a/main/reference/jp/examples/path_canonicalize/index.html +++ b/main/reference/jp/examples/path_canonicalize/index.html @@ -1 +1 @@ - path_canonicalize - Chainsaw
Skip to content

path_canonicalize

Signature

path_canonicalize(string)

Description

Normalizes or canonicalizes a given path by removing excess slashes.

Examples

TODO

\ No newline at end of file + path_canonicalize - Chainsaw
Skip to content

path_canonicalize

Signature

path_canonicalize(string)

Description

Normalizes or canonicalizes a given path by removing excess slashes.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/pattern_match/index.html b/main/reference/jp/examples/pattern_match/index.html index 990bbb915..deba3617e 100644 --- a/main/reference/jp/examples/pattern_match/index.html +++ b/main/reference/jp/examples/pattern_match/index.html @@ -1 +1 @@ - pattern_match - Chainsaw
Skip to content

pattern_match

Signature

pattern_match(string, string|number)

Description

'*' matches zero or more alphanumeric characters, '?' matches a single alphanumeric character.

Examples

TODO

\ No newline at end of file + pattern_match - Chainsaw
Skip to content

pattern_match

Signature

pattern_match(string, string|number)

Description

'*' matches zero or more alphanumeric characters, '?' matches a single alphanumeric character.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/random/index.html b/main/reference/jp/examples/random/index.html index a02a261ba..e9eea74a7 100644 --- a/main/reference/jp/examples/random/index.html +++ b/main/reference/jp/examples/random/index.html @@ -1 +1 @@ - random - Chainsaw
Skip to content

random

Signature

random(string)

Description

Generates a random sequence of characters.

Examples

TODO

\ No newline at end of file + random - Chainsaw
Skip to content

random

Signature

random(string)

Description

Generates a random sequence of characters.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/regex_match/index.html b/main/reference/jp/examples/regex_match/index.html index 9517107e3..a2b1d1e1c 100644 --- a/main/reference/jp/examples/regex_match/index.html +++ b/main/reference/jp/examples/regex_match/index.html @@ -1 +1 @@ - regex_match - Chainsaw
Skip to content

regex_match

Signature

regex_match(string, string|number)

Description

First string is the regular exression which is compared with second input which can be a number or string.

Examples

TODO

\ No newline at end of file + regex_match - Chainsaw
Skip to content

regex_match

Signature

regex_match(string, string|number)

Description

First string is the regular exression which is compared with second input which can be a number or string.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/regex_replace_all/index.html b/main/reference/jp/examples/regex_replace_all/index.html index 2ed5bc461..fc4e700b6 100644 --- a/main/reference/jp/examples/regex_replace_all/index.html +++ b/main/reference/jp/examples/regex_replace_all/index.html @@ -1 +1 @@ - regex_replace_all - Chainsaw
Skip to content

regex_replace_all

Signature

regex_replace_all(string, string|number, string|number)

Description

Converts all parameters to string.

Examples

TODO

\ No newline at end of file + regex_replace_all - Chainsaw
Skip to content

regex_replace_all

Signature

regex_replace_all(string, string|number, string|number)

Description

Converts all parameters to string.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/regex_replace_all_literal/index.html b/main/reference/jp/examples/regex_replace_all_literal/index.html index 76db83852..d566c8999 100644 --- a/main/reference/jp/examples/regex_replace_all_literal/index.html +++ b/main/reference/jp/examples/regex_replace_all_literal/index.html @@ -1 +1 @@ - regex_replace_all_literal - Chainsaw
Skip to content

regex_replace_all_literal

Signature

regex_replace_all_literal(string, string|number, string|number)

Description

Converts all parameters to string.

Examples

TODO

\ No newline at end of file + regex_replace_all_literal - Chainsaw
Skip to content

regex_replace_all_literal

Signature

regex_replace_all_literal(string, string|number, string|number)

Description

Converts all parameters to string.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/replace/index.html b/main/reference/jp/examples/replace/index.html index 3cc3314d6..cd580524f 100644 --- a/main/reference/jp/examples/replace/index.html +++ b/main/reference/jp/examples/replace/index.html @@ -1,3 +1,3 @@ - replace - Chainsaw
Skip to content

replace

Signature

replace(string, string, string, number)

Description

Replaces a specified number of instances of the source string with the replacement string in a parent.

Examples

replace('foobar', 'oo', 'ii') == 'fiibar'
+ replace - Chainsaw      

replace

Signature

replace(string, string, string, number)

Description

Replaces a specified number of instances of the source string with the replacement string in a parent.

Examples

replace('foobar', 'oo', 'ii') == 'fiibar'
 
replace('foobar', 'o', 'i', `1`) == 'fiobar'
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/replace_all/index.html b/main/reference/jp/examples/replace_all/index.html index 50bda5fb3..682ec2855 100644 --- a/main/reference/jp/examples/replace_all/index.html +++ b/main/reference/jp/examples/replace_all/index.html @@ -1 +1 @@ - replace_all - Chainsaw
Skip to content

replace_all

Signature

replace_all(string, string, string)

Description

Replace all instances of one string with another in an overall parent string.

Examples

TODO

\ No newline at end of file + replace_all - Chainsaw
Skip to content

replace_all

Signature

replace_all(string, string, string)

Description

Replace all instances of one string with another in an overall parent string.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/reverse/index.html b/main/reference/jp/examples/reverse/index.html index 40991ce86..84b49575d 100644 --- a/main/reference/jp/examples/reverse/index.html +++ b/main/reference/jp/examples/reverse/index.html @@ -1,3 +1,3 @@ - reverse - Chainsaw
Skip to content

reverse

Signature

reverse(array|string)

Description

Reverses the input string or array and returns the result.

Examples

reverse('abcd') == 'dcba'
+ reverse - Chainsaw      

reverse

Signature

reverse(array|string)

Description

Reverses the input string or array and returns the result.

Examples

reverse('abcd') == 'dcba'
 
reverse([`1`, `2`, `3`, `4`]) == [`4`, `3`, `2`, `1`]
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/round/index.html b/main/reference/jp/examples/round/index.html index f2999bbec..2ef26cd6e 100644 --- a/main/reference/jp/examples/round/index.html +++ b/main/reference/jp/examples/round/index.html @@ -1 +1 @@ - round - Chainsaw
Skip to content

round

Signature

round(number, number)

Description

Does roundoff to upto the given decimal places.

Examples

TODO

\ No newline at end of file + round - Chainsaw
Skip to content

round

Signature

round(number, number)

Description

Does roundoff to upto the given decimal places.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/semver_compare/index.html b/main/reference/jp/examples/semver_compare/index.html index aec2844da..2004d4d1f 100644 --- a/main/reference/jp/examples/semver_compare/index.html +++ b/main/reference/jp/examples/semver_compare/index.html @@ -1 +1 @@ - semver_compare - Chainsaw
Skip to content

semver_compare

Signature

semver_compare(string, string)

Description

Compares two strings which comply with the semantic versioning schema and outputs a boolean response as to the position of the second relative to the first.

Examples

TODO

\ No newline at end of file + semver_compare - Chainsaw
Skip to content

semver_compare

Signature

semver_compare(string, string)

Description

Compares two strings which comply with the semantic versioning schema and outputs a boolean response as to the position of the second relative to the first.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/sort/index.html b/main/reference/jp/examples/sort/index.html index 30dde6a21..991025224 100644 --- a/main/reference/jp/examples/sort/index.html +++ b/main/reference/jp/examples/sort/index.html @@ -1,2 +1,2 @@ - sort - Chainsaw
Skip to content

sort

Signature

sort(array[string]|array[number])

Description

This function accepts an array argument and returns the sorted elements as an array.

Examples

sort(['b', 'a', 'c']) == ['a', 'b', 'c']
-
\ No newline at end of file + sort - Chainsaw
Skip to content

sort

Signature

sort(array[string]|array[number])

Description

This function accepts an array argument and returns the sorted elements as an array.

Examples

sort(['b', 'a', 'c']) == ['a', 'b', 'c']
+
\ No newline at end of file diff --git a/main/reference/jp/examples/sort_by/index.html b/main/reference/jp/examples/sort_by/index.html index 876ced3de..230de94a7 100644 --- a/main/reference/jp/examples/sort_by/index.html +++ b/main/reference/jp/examples/sort_by/index.html @@ -1 +1 @@ - sort_by - Chainsaw
Skip to content

sort_by

Signature

sort_by(array, expref)

Description

This function accepts an array argument and returns the sorted elements as an array using a custom expression to compute the associated value for each element.

Examples

TODO

\ No newline at end of file + sort_by - Chainsaw
Skip to content

sort_by

Signature

sort_by(array, expref)

Description

This function accepts an array argument and returns the sorted elements as an array using a custom expression to compute the associated value for each element.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/split/index.html b/main/reference/jp/examples/split/index.html index 653c4b1b5..45dc63938 100644 --- a/main/reference/jp/examples/split/index.html +++ b/main/reference/jp/examples/split/index.html @@ -1,2 +1,2 @@ - split - Chainsaw
Skip to content

split

Signature

split(string, string)

Description

Splits the first string when the second string is found and converts it into an array.

Examples

split('average|-|min|-|max|-|mean|-|median', '|-|', `3`) == ['average', 'min', 'max', 'mean|-|median']
-
\ No newline at end of file + split - Chainsaw
Skip to content

split

Signature

split(string, string)

Description

Splits the first string when the second string is found and converts it into an array.

Examples

split('average|-|min|-|max|-|mean|-|median', '|-|', `3`) == ['average', 'min', 'max', 'mean|-|median']
+
\ No newline at end of file diff --git a/main/reference/jp/examples/starts_with/index.html b/main/reference/jp/examples/starts_with/index.html index 0ae3a5726..ef1925a1c 100644 --- a/main/reference/jp/examples/starts_with/index.html +++ b/main/reference/jp/examples/starts_with/index.html @@ -1,3 +1,3 @@ - starts_with - Chainsaw
Skip to content

starts_with

Signature

starts_with(string, string)

Description

Reports whether the input string begins with the provided string prefix argument.

Examples

starts_with('foobar', 'foo') == `true`
+ starts_with - Chainsaw      

starts_with

Signature

starts_with(string, string)

Description

Reports whether the input string begins with the provided string prefix argument.

Examples

starts_with('foobar', 'foo') == `true`
 
starts_with('foobar', 'bar') == `false`
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/subtract/index.html b/main/reference/jp/examples/subtract/index.html index aafc88e44..db92bd0d5 100644 --- a/main/reference/jp/examples/subtract/index.html +++ b/main/reference/jp/examples/subtract/index.html @@ -1 +1 @@ - subtract - Chainsaw
Skip to content

subtract

Signature

subtract(any, any)

Description

Does arithmetic subtraction of two specified values of numbers, quantities, and durations.

Examples

TODO

\ No newline at end of file + subtract - Chainsaw
Skip to content

subtract

Signature

subtract(any, any)

Description

Does arithmetic subtraction of two specified values of numbers, quantities, and durations.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/sum/index.html b/main/reference/jp/examples/sum/index.html index 837a27646..4c7abeb43 100644 --- a/main/reference/jp/examples/sum/index.html +++ b/main/reference/jp/examples/sum/index.html @@ -1,3 +1,3 @@ - sum - Chainsaw
Skip to content

sum

Signature

sum(array)

Description

Does arithmetic addition of specified array of values of numbers, quantities, and durations.

Examples

sum(`[]`) == `0`
+ sum - Chainsaw      

sum

Signature

sum(array)

Description

Does arithmetic addition of specified array of values of numbers, quantities, and durations.

Examples

sum(`[]`) == `0`
 
sum([`10`, `15`]) == `25`
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/time_add/index.html b/main/reference/jp/examples/time_add/index.html index 0bebedcc9..2ed5c753d 100644 --- a/main/reference/jp/examples/time_add/index.html +++ b/main/reference/jp/examples/time_add/index.html @@ -1 +1 @@ - time_add - Chainsaw
Skip to content

time_add

Signature

time_add(string, string)

Description

Adds duration (second string) to a time value (first string).

Examples

TODO

\ No newline at end of file + time_add - Chainsaw
Skip to content

time_add

Signature

time_add(string, string)

Description

Adds duration (second string) to a time value (first string).

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_after/index.html b/main/reference/jp/examples/time_after/index.html index b985fc6a6..f7093323d 100644 --- a/main/reference/jp/examples/time_after/index.html +++ b/main/reference/jp/examples/time_after/index.html @@ -1 +1 @@ - time_after - Chainsaw
Skip to content

time_after

Signature

time_after(string, string)

Description

Checks if a time is after another time, both in RFC3339 format.

Examples

TODO

\ No newline at end of file + time_after - Chainsaw
Skip to content

time_after

Signature

time_after(string, string)

Description

Checks if a time is after another time, both in RFC3339 format.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_before/index.html b/main/reference/jp/examples/time_before/index.html index de3dc7512..01408bebe 100644 --- a/main/reference/jp/examples/time_before/index.html +++ b/main/reference/jp/examples/time_before/index.html @@ -1 +1 @@ - time_before - Chainsaw
Skip to content

time_before

Signature

time_before(string, string)

Description

Checks if a time is before another time, both in RFC3339 format.

Examples

TODO

\ No newline at end of file + time_before - Chainsaw
Skip to content

time_before

Signature

time_before(string, string)

Description

Checks if a time is before another time, both in RFC3339 format.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_between/index.html b/main/reference/jp/examples/time_between/index.html index 20ece8a7e..ecb07d1d2 100644 --- a/main/reference/jp/examples/time_between/index.html +++ b/main/reference/jp/examples/time_between/index.html @@ -1 +1 @@ - time_between - Chainsaw
Skip to content

time_between

Signature

time_between(string, string, string)

Description

Checks if a time is between a start and end time, all in RFC3339 format.

Examples

TODO

\ No newline at end of file + time_between - Chainsaw
Skip to content

time_between

Signature

time_between(string, string, string)

Description

Checks if a time is between a start and end time, all in RFC3339 format.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_diff/index.html b/main/reference/jp/examples/time_diff/index.html index 3acae15a9..f2ce937f5 100644 --- a/main/reference/jp/examples/time_diff/index.html +++ b/main/reference/jp/examples/time_diff/index.html @@ -1 +1 @@ - time_diff - Chainsaw
Skip to content

time_diff

Signature

time_diff(string, string)

Description

Calculate the difference between a start and end date in RFC3339 format.

Examples

TODO

\ No newline at end of file + time_diff - Chainsaw
Skip to content

time_diff

Signature

time_diff(string, string)

Description

Calculate the difference between a start and end date in RFC3339 format.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_now/index.html b/main/reference/jp/examples/time_now/index.html index 94e3c34fa..64e6be0c4 100644 --- a/main/reference/jp/examples/time_now/index.html +++ b/main/reference/jp/examples/time_now/index.html @@ -1 +1 @@ - time_now - Chainsaw
Skip to content

time_now

Signature

time_now()

Description

Returns current time in RFC 3339 format.

Examples

TODO

\ No newline at end of file + time_now - Chainsaw
Skip to content

time_now

Signature

time_now()

Description

Returns current time in RFC 3339 format.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_now_utc/index.html b/main/reference/jp/examples/time_now_utc/index.html index d4c92edd8..74244bc19 100644 --- a/main/reference/jp/examples/time_now_utc/index.html +++ b/main/reference/jp/examples/time_now_utc/index.html @@ -1 +1 @@ - time_now_utc - Chainsaw
Skip to content

time_now_utc

Signature

time_now_utc()

Description

Returns current UTC time in RFC 3339 format.

Examples

TODO

\ No newline at end of file + time_now_utc - Chainsaw
Skip to content

time_now_utc

Signature

time_now_utc()

Description

Returns current UTC time in RFC 3339 format.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_parse/index.html b/main/reference/jp/examples/time_parse/index.html index 8d42dbf6d..27d640bed 100644 --- a/main/reference/jp/examples/time_parse/index.html +++ b/main/reference/jp/examples/time_parse/index.html @@ -1 +1 @@ - time_parse - Chainsaw
Skip to content

time_parse

Signature

time_parse(string, string)

Description

Changes a time value of a given layout to RFC 3339.

Examples

TODO

\ No newline at end of file + time_parse - Chainsaw
Skip to content

time_parse

Signature

time_parse(string, string)

Description

Changes a time value of a given layout to RFC 3339.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_since/index.html b/main/reference/jp/examples/time_since/index.html index 143f59a8b..6013c0f35 100644 --- a/main/reference/jp/examples/time_since/index.html +++ b/main/reference/jp/examples/time_since/index.html @@ -1 +1 @@ - time_since - Chainsaw
Skip to content

time_since

Signature

time_since(string, string, string)

Description

Calculate the difference between a start and end period of time where the end may either be a static definition or the then-current time.

Examples

TODO

\ No newline at end of file + time_since - Chainsaw
Skip to content

time_since

Signature

time_since(string, string, string)

Description

Calculate the difference between a start and end period of time where the end may either be a static definition or the then-current time.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_to_cron/index.html b/main/reference/jp/examples/time_to_cron/index.html index f09575144..f2e2652cb 100644 --- a/main/reference/jp/examples/time_to_cron/index.html +++ b/main/reference/jp/examples/time_to_cron/index.html @@ -1 +1 @@ - time_to_cron - Chainsaw
Skip to content

time_to_cron

Signature

time_to_cron(string)

Description

Converts a time (RFC 3339) to a cron expression (string).

Examples

TODO

\ No newline at end of file + time_to_cron - Chainsaw
Skip to content

time_to_cron

Signature

time_to_cron(string)

Description

Converts a time (RFC 3339) to a cron expression (string).

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_truncate/index.html b/main/reference/jp/examples/time_truncate/index.html index bbfa8dc2d..8acd16439 100644 --- a/main/reference/jp/examples/time_truncate/index.html +++ b/main/reference/jp/examples/time_truncate/index.html @@ -1 +1 @@ - time_truncate - Chainsaw
Skip to content

time_truncate

Signature

time_truncate(string, string)

Description

Returns the result of rounding time down to a multiple of duration.

Examples

TODO

\ No newline at end of file + time_truncate - Chainsaw
Skip to content

time_truncate

Signature

time_truncate(string, string)

Description

Returns the result of rounding time down to a multiple of duration.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/time_utc/index.html b/main/reference/jp/examples/time_utc/index.html index 5082ab7c9..749f4d108 100644 --- a/main/reference/jp/examples/time_utc/index.html +++ b/main/reference/jp/examples/time_utc/index.html @@ -1 +1 @@ - time_utc - Chainsaw
Skip to content

time_utc

Signature

time_utc(string)

Description

Calcutes time in UTC from a given time in RFC 3339 format.

Examples

TODO

\ No newline at end of file + time_utc - Chainsaw
Skip to content

time_utc

Signature

time_utc(string)

Description

Calcutes time in UTC from a given time in RFC 3339 format.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/to_array/index.html b/main/reference/jp/examples/to_array/index.html index 3f6478d90..7f3fd5614 100644 --- a/main/reference/jp/examples/to_array/index.html +++ b/main/reference/jp/examples/to_array/index.html @@ -1,4 +1,4 @@ - to_array - Chainsaw
Skip to content

to_array

Signature

to_array(any)

Description

Returns a one element array containing the passed in argument, or the passed in value if it's an array.

Examples

to_array(`true`) == [`true`]
+ to_array - Chainsaw      

to_array

Signature

to_array(any)

Description

Returns a one element array containing the passed in argument, or the passed in value if it's an array.

Examples

to_array(`true`) == [`true`]
 
to_array([`10`, `15`, `20`]) == [`10`, `15`, `20`]
 
to_array(`[]`) == []
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/to_boolean/index.html b/main/reference/jp/examples/to_boolean/index.html index d2e8b6402..19dddb3ff 100644 --- a/main/reference/jp/examples/to_boolean/index.html +++ b/main/reference/jp/examples/to_boolean/index.html @@ -1 +1 @@ - to_boolean - Chainsaw
Skip to content

to_boolean

Signature

to_boolean(string)

Description

It returns true or false for any string, such as 'True', 'TruE', 'False', 'FAlse', 'faLSE', etc.

Examples

TODO

\ No newline at end of file + to_boolean - Chainsaw
Skip to content

to_boolean

Signature

to_boolean(string)

Description

It returns true or false for any string, such as 'True', 'TruE', 'False', 'FAlse', 'faLSE', etc.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/to_lower/index.html b/main/reference/jp/examples/to_lower/index.html index 3a2e6e7aa..bfde35560 100644 --- a/main/reference/jp/examples/to_lower/index.html +++ b/main/reference/jp/examples/to_lower/index.html @@ -1,2 +1,2 @@ - to_lower - Chainsaw
Skip to content

to_lower

Signature

to_lower(string)

Description

Takes in a string and outputs the same string with all lower-case letters.

Examples

lower('FOOBAR') == 'foobar'
-
\ No newline at end of file + to_lower - Chainsaw
Skip to content

to_lower

Signature

to_lower(string)

Description

Takes in a string and outputs the same string with all lower-case letters.

Examples

lower('FOOBAR') == 'foobar'
+
\ No newline at end of file diff --git a/main/reference/jp/examples/to_number/index.html b/main/reference/jp/examples/to_number/index.html index ab6fd7f3d..aa8152995 100644 --- a/main/reference/jp/examples/to_number/index.html +++ b/main/reference/jp/examples/to_number/index.html @@ -1,4 +1,4 @@ - to_number - Chainsaw
Skip to content

to_number

Signature

to_number(any)

Description

Returns the parsed number.

Examples

to_number('1.0') == `1`
+ to_number - Chainsaw      

to_number

Signature

to_number(any)

Description

Returns the parsed number.

Examples

to_number('1.0') == `1`
 
to_number(`1.0`) == `1`
 
to_number(`false`) == null
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/to_string/index.html b/main/reference/jp/examples/to_string/index.html index 9e15c90d7..153205871 100644 --- a/main/reference/jp/examples/to_string/index.html +++ b/main/reference/jp/examples/to_string/index.html @@ -1,5 +1,5 @@ - to_string - Chainsaw
Skip to content

to_string

Signature

to_string(any)

Description

The JSON encoded value of the given argument.

Examples

to_string(`2`) == '2'
+ to_string - Chainsaw      

to_string

Signature

to_string(any)

Description

The JSON encoded value of the given argument.

Examples

to_string(`2`) == '2'
 
to_string('foobar') == 'foobar'
 
to_string(null) == 'null'
 
to_string({bar:'bam',foo:'baz'}) == '{"bar":"bam","foo":"baz"}'
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/to_upper/index.html b/main/reference/jp/examples/to_upper/index.html index d706ce1c4..fe4d48195 100644 --- a/main/reference/jp/examples/to_upper/index.html +++ b/main/reference/jp/examples/to_upper/index.html @@ -1,2 +1,2 @@ - to_upper - Chainsaw
Skip to content

to_upper

Signature

to_upper(string)

Description

Takes in a string and outputs the same string with all upper-case letters.

Examples

upper('foobar') == 'FOOBAR'
-
\ No newline at end of file + to_upper - Chainsaw
Skip to content

to_upper

Signature

to_upper(string)

Description

Takes in a string and outputs the same string with all upper-case letters.

Examples

upper('foobar') == 'FOOBAR'
+
\ No newline at end of file diff --git a/main/reference/jp/examples/trim/index.html b/main/reference/jp/examples/trim/index.html index 466e211fb..02f5858cc 100644 --- a/main/reference/jp/examples/trim/index.html +++ b/main/reference/jp/examples/trim/index.html @@ -1,3 +1,3 @@ - trim - Chainsaw
Skip to content

trim

Signature

trim(string, string)

Description

Trims both ends of the source string by characters appearing in the second string.

Examples

trim(' foobar ', 'fbr ') == 'ooba'
+ trim - Chainsaw      

trim

Signature

trim(string, string)

Description

Trims both ends of the source string by characters appearing in the second string.

Examples

trim(' foobar ', 'fbr ') == 'ooba'
 
trim(' foobar ', 'fbr') == ' foobar '
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/trim_left/index.html b/main/reference/jp/examples/trim_left/index.html index 24a02d551..06187ed10 100644 --- a/main/reference/jp/examples/trim_left/index.html +++ b/main/reference/jp/examples/trim_left/index.html @@ -1,3 +1,3 @@ - trim_left - Chainsaw
Skip to content

trim_left

Signature

trim_left(string, string)

Description

Removes the leading characters found in the passed in string argument.

Examples

trim_left(' foobar ', 'fbr ') == 'oobar '
+ trim_left - Chainsaw      

trim_left

Signature

trim_left(string, string)

Description

Removes the leading characters found in the passed in string argument.

Examples

trim_left(' foobar ', 'fbr ') == 'oobar '
 
trim_left(' foobar ', 'fbr') == ' foobar '
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/trim_prefix/index.html b/main/reference/jp/examples/trim_prefix/index.html index 74ba68a99..2258600a9 100644 --- a/main/reference/jp/examples/trim_prefix/index.html +++ b/main/reference/jp/examples/trim_prefix/index.html @@ -1 +1 @@ - trim_prefix - Chainsaw
Skip to content

trim_prefix

Signature

trim_prefix(string, string)

Description

Trims the second string prefix from the first string if the first string starts with the prefix.

Examples

TODO

\ No newline at end of file + trim_prefix - Chainsaw
Skip to content

trim_prefix

Signature

trim_prefix(string, string)

Description

Trims the second string prefix from the first string if the first string starts with the prefix.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/trim_right/index.html b/main/reference/jp/examples/trim_right/index.html index 07c9be188..54a62f0b7 100644 --- a/main/reference/jp/examples/trim_right/index.html +++ b/main/reference/jp/examples/trim_right/index.html @@ -1,3 +1,3 @@ - trim_right - Chainsaw
Skip to content

trim_right

Signature

trim_right(string, string)

Description

Removes the trailing characters found in the passed in string argument.

Examples

trim_right(' foobar ', 'fbr ') == ' fooba'
+ trim_right - Chainsaw      

trim_right

Signature

trim_right(string, string)

Description

Removes the trailing characters found in the passed in string argument.

Examples

trim_right(' foobar ', 'fbr ') == ' fooba'
 
trim_right(' foobar ', 'fbr') == ' foobar '
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/trim_space/index.html b/main/reference/jp/examples/trim_space/index.html index 9ce8b165d..d847770e3 100644 --- a/main/reference/jp/examples/trim_space/index.html +++ b/main/reference/jp/examples/trim_space/index.html @@ -1,2 +1,2 @@ - trim_space - Chainsaw
Skip to content

trim_space

Signature

trim_space(string)

Description

Trims leading and trailing spaces from the string passed in argument.

Examples

trim_space('    foobar  ') == 'foobar'
-
\ No newline at end of file + trim_space - Chainsaw
Skip to content

trim_space

Signature

trim_space(string)

Description

Trims leading and trailing spaces from the string passed in argument.

Examples

trim_space('    foobar  ') == 'foobar'
+
\ No newline at end of file diff --git a/main/reference/jp/examples/truncate/index.html b/main/reference/jp/examples/truncate/index.html index 7f8b1146f..e0b3fa70a 100644 --- a/main/reference/jp/examples/truncate/index.html +++ b/main/reference/jp/examples/truncate/index.html @@ -1 +1 @@ - truncate - Chainsaw
Skip to content

truncate

Signature

truncate(string, number)

Description

Length argument must be enclosed in backticks; ex. "{{request.object.metadata.name | truncate(@, 9)}}".

Examples

TODO

\ No newline at end of file + truncate - Chainsaw
Skip to content

truncate

Signature

truncate(string, number)

Description

Length argument must be enclosed in backticks; ex. "{{request.object.metadata.name | truncate(@, 9)}}".

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/type/index.html b/main/reference/jp/examples/type/index.html index db4ca38bb..e84e8cce6 100644 --- a/main/reference/jp/examples/type/index.html +++ b/main/reference/jp/examples/type/index.html @@ -1,4 +1,4 @@ - type - Chainsaw
Skip to content

type

Signature

type(any)

Description

Returns the JavaScript type of the given argument as a string value.

Examples

type(`false`) == 'boolean'
+ type - Chainsaw      

type

Signature

type(any)

Description

Returns the JavaScript type of the given argument as a string value.

Examples

type(`false`) == 'boolean'
 
type(null) == 'null'
 
type('foobar') == 'string'
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/upper/index.html b/main/reference/jp/examples/upper/index.html index fd9b23246..11d3828d2 100644 --- a/main/reference/jp/examples/upper/index.html +++ b/main/reference/jp/examples/upper/index.html @@ -1,2 +1,2 @@ - upper - Chainsaw
Skip to content

upper

Signature

upper(string)

Description

Returns the given string with all Unicode letters mapped to their upper case.

Examples

upper('foobar') == 'FOOBAR'
-
\ No newline at end of file + upper - Chainsaw
Skip to content

upper

Signature

upper(string)

Description

Returns the given string with all Unicode letters mapped to their upper case.

Examples

upper('foobar') == 'FOOBAR'
+
\ No newline at end of file diff --git a/main/reference/jp/examples/values/index.html b/main/reference/jp/examples/values/index.html index 7d4f3ac50..6bbad542d 100644 --- a/main/reference/jp/examples/values/index.html +++ b/main/reference/jp/examples/values/index.html @@ -1,2 +1,2 @@ - values - Chainsaw
Skip to content

values

Signature

values(object)

Description

Returns the values of the provided object.

Examples

values({bar:'bam',foo:'baz'}) == ['bam','baz']
-
\ No newline at end of file + values - Chainsaw
Skip to content

values

Signature

values(object)

Description

Returns the values of the provided object.

Examples

values({bar:'bam',foo:'baz'}) == ['bam','baz']
+
\ No newline at end of file diff --git a/main/reference/jp/examples/wildcard/index.html b/main/reference/jp/examples/wildcard/index.html index 2d73b27b2..bc8acc13e 100644 --- a/main/reference/jp/examples/wildcard/index.html +++ b/main/reference/jp/examples/wildcard/index.html @@ -1,3 +1,3 @@ - wildcard - Chainsaw
Skip to content

wildcard

Signature

wildcard(string, string)

Description

Compares a wildcard pattern with a given string and returns if they match or not.

Examples

wildcard('foo*', 'foobar') == `true`
+ wildcard - Chainsaw      

wildcard

Signature

wildcard(string, string)

Description

Compares a wildcard pattern with a given string and returns if they match or not.

Examples

wildcard('foo*', 'foobar') == `true`
 
wildcard('fooba?', 'foobar') == `true`
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/x509_decode/index.html b/main/reference/jp/examples/x509_decode/index.html index 58df80e3e..abced808e 100644 --- a/main/reference/jp/examples/x509_decode/index.html +++ b/main/reference/jp/examples/x509_decode/index.html @@ -1 +1 @@ - x509_decode - Chainsaw
Skip to content

x509_decode

Signature

x509_decode(string)

Description

Decodes an x.509 certificate to an object. you may also use this in conjunction with base64_decode jmespath function to decode a base64-encoded certificate.

Examples

TODO

\ No newline at end of file + x509_decode - Chainsaw
Skip to content

x509_decode

Signature

x509_decode(string)

Description

Decodes an x.509 certificate to an object. you may also use this in conjunction with base64_decode jmespath function to decode a base64-encoded certificate.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/x_k8s_exists/index.html b/main/reference/jp/examples/x_k8s_exists/index.html index 301bc661f..9b762e495 100644 --- a/main/reference/jp/examples/x_k8s_exists/index.html +++ b/main/reference/jp/examples/x_k8s_exists/index.html @@ -1,4 +1,4 @@ - x_k8s_exists - Chainsaw
Skip to content

x_k8s_exists

Signature

x_k8s_exists(any, string, string, string, string)

Description

Checks if a given resource exists in a Kubernetes cluster.

Examples

Clustered resources

For clustered resources, you can leave the namespace empty ''.

# `$client` is a binding pointing to a Kubernetes client
+ x_k8s_exists - Chainsaw      

x_k8s_exists

Signature

x_k8s_exists(any, string, string, string, string)

Description

Checks if a given resource exists in a Kubernetes cluster.

Examples

Clustered resources

For clustered resources, you can leave the namespace empty ''.

# `$client` is a binding pointing to a Kubernetes client
 
 x_k8s_exists($client, 'apps/v1', 'Deployment', 'crossplane-system', 'crossplane')
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/x_k8s_get/index.html b/main/reference/jp/examples/x_k8s_get/index.html index 6be3aae3f..8f215e92d 100644 --- a/main/reference/jp/examples/x_k8s_get/index.html +++ b/main/reference/jp/examples/x_k8s_get/index.html @@ -1,4 +1,4 @@ - x_k8s_get - Chainsaw
Skip to content

x_k8s_get

Signature

x_k8s_get(any, string, string, string, string)

Description

Gets a resource from a Kubernetes cluster.

Examples

Clustered resources

For clustered resources, you can leave the namespace empty ''.

# `$client` is a binding pointing to a Kubernetes client
+ x_k8s_get - Chainsaw      

x_k8s_get

Signature

x_k8s_get(any, string, string, string, string)

Description

Gets a resource from a Kubernetes cluster.

Examples

Clustered resources

For clustered resources, you can leave the namespace empty ''.

# `$client` is a binding pointing to a Kubernetes client
 
 x_k8s_get($client, 'apps/v1', 'Deployment', 'crossplane-system', 'crossplane')
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/x_k8s_list/index.html b/main/reference/jp/examples/x_k8s_list/index.html index 6128f0fbb..f28ef2c3b 100644 --- a/main/reference/jp/examples/x_k8s_list/index.html +++ b/main/reference/jp/examples/x_k8s_list/index.html @@ -1,4 +1,4 @@ - x_k8s_list - Chainsaw
Skip to content

x_k8s_list

Signature

x_k8s_list(any, string, string, string)

Description

Lists resources from a Kubernetes cluster.

Examples

Clustered resources

For clustered resources, you can leave the namespace empty ''.

# `$client` is a binding pointing to a Kubernetes client
+ x_k8s_list - Chainsaw      

x_k8s_list

Signature

x_k8s_list(any, string, string, string)

Description

Lists resources from a Kubernetes cluster.

Examples

Clustered resources

For clustered resources, you can leave the namespace empty ''.

# `$client` is a binding pointing to a Kubernetes client
 
 x_k8s_list($client, 'apps/v1', 'Deployment', 'crossplane-system')
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/x_k8s_resource_exists/index.html b/main/reference/jp/examples/x_k8s_resource_exists/index.html index 425647b6f..6241fae09 100644 --- a/main/reference/jp/examples/x_k8s_resource_exists/index.html +++ b/main/reference/jp/examples/x_k8s_resource_exists/index.html @@ -1,4 +1,4 @@ - x_k8s_resource_exists - Chainsaw
Skip to content

x_k8s_resource_exists

Signature

x_k8s_resource_exists(any, string, string)

Description

Checks if a given resource type is available in a Kubernetes cluster.

Examples

Clustered resources

For clustered resources, you can leave the namespace empty ''.

# `$client` is a binding pointing to a Kubernetes client
+ x_k8s_resource_exists - Chainsaw      

x_k8s_resource_exists

Signature

x_k8s_resource_exists(any, string, string)

Description

Checks if a given resource type is available in a Kubernetes cluster.

Examples

Clustered resources

For clustered resources, you can leave the namespace empty ''.

# `$client` is a binding pointing to a Kubernetes client
 
 x_k8s_resource_exists($client, 'apps/v1', 'Deployment')
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/x_k8s_server_version/index.html b/main/reference/jp/examples/x_k8s_server_version/index.html index f0db13913..dea82ea02 100644 --- a/main/reference/jp/examples/x_k8s_server_version/index.html +++ b/main/reference/jp/examples/x_k8s_server_version/index.html @@ -1,4 +1,4 @@ - x_k8s_server_version - Chainsaw
Skip to content

x_k8s_server_version

Signature

x_k8s_server_version(any)

Description

Returns the version of a Kubernetes cluster.

Examples

# `$client` is a binding pointing to a Kubernetes client
+ x_k8s_server_version - Chainsaw      

x_k8s_server_version

Signature

x_k8s_server_version(any)

Description

Returns the version of a Kubernetes cluster.

Examples

# `$client` is a binding pointing to a Kubernetes client
 
 x_k8s_server_version($client)
-
\ No newline at end of file +
\ No newline at end of file diff --git a/main/reference/jp/examples/x_metrics_decode/index.html b/main/reference/jp/examples/x_metrics_decode/index.html index a5c1c1b75..ec3f8e635 100644 --- a/main/reference/jp/examples/x_metrics_decode/index.html +++ b/main/reference/jp/examples/x_metrics_decode/index.html @@ -1 +1 @@ - x_metrics_decode - Chainsaw
Skip to content

x_metrics_decode

Signature

x_metrics_decode(string)

Description

Decodes metrics in the Prometheus text format.

Examples

TODO

\ No newline at end of file + x_metrics_decode - Chainsaw
Skip to content

x_metrics_decode

Signature

x_metrics_decode(string)

Description

Decodes metrics in the Prometheus text format.

Examples

TODO

\ No newline at end of file diff --git a/main/reference/jp/examples/zip/index.html b/main/reference/jp/examples/zip/index.html index 8d4651ba4..6b0d65da2 100644 --- a/main/reference/jp/examples/zip/index.html +++ b/main/reference/jp/examples/zip/index.html @@ -1,2 +1,2 @@ - zip - Chainsaw
Skip to content

zip

Signature

zip(array, array)

Description

Accepts one or more arrays as arguments and returns an array of arrays in which the i-th array contains the i-th element from each of the argument arrays. The returned array is truncated to the length of the shortest argument array.

Examples

zip(['a', 'b'], [`1`, `2`]) == [['a', `1`], ['b', `2`]]
-
\ No newline at end of file + zip - Chainsaw
Skip to content

zip

Signature

zip(array, array)

Description

Accepts one or more arrays as arguments and returns an array of arrays in which the i-th array contains the i-th element from each of the argument arrays. The returned array is truncated to the length of the shortest argument array.

Examples

zip(['a', 'b'], [`1`, `2`]) == [['a', `1`], ['b', `2`]]
+
\ No newline at end of file diff --git a/main/reference/jp/functions/index.html b/main/reference/jp/functions/index.html index a86de80f6..8781db87b 100644 --- a/main/reference/jp/functions/index.html +++ b/main/reference/jp/functions/index.html @@ -1 +1 @@ - Functions - Chainsaw
Skip to content

Functions

Experimental functions

Experimental functions are denoted by the x_ prefix.

These are functions that are subject to signature change in a future version.

built-in functions

Name Description
abs Returns the absolute value of the provided argument.
avg Returns the average of the elements in the provided array. An empty array will produce a return value of null.
ceil Returns the next highest integer value by rounding up if necessary.
contains Returns true if the given subject contains the provided search value. If the subject is an array, this function returns true if one of the elements in the array is equal to the provided search value. If the provided subject is a string, this function returns true if the string contains the provided search argument.
ends_with Reports whether the given string ends with the provided suffix argument.
find_first Returns the zero-based index of the first occurence where the substring appears in a string or null if it does not appear.
find_last Returns the zero-based index of the last occurence where the substring appears in a string or null if it does not appear.
floor Returns the next lowest integer value by rounding down if necessary.
from_items Returns an object from the provided array of key value pairs. This function is the inversed of the items() function.
group_by Groups an array of objects using an expression as the group key.
items Converts a given object into an array of key-value pairs.
join Returns all of the elements from the provided array joined together using the glue argument as a separator between each.
keys Returns an array containing the keys of the provided object.
length Returns the length of the given argument. If the argument is a string this function returns the number of code points in the string. If the argument is an array this function returns the number of elements in the array. If the argument is an object this function returns the number of key-value pairs in the object.
lower Returns the given string with all Unicode letters mapped to their lower case.
map Transforms elements in a given array and returns the result.
max Returns the highest found element in the provided array argument. An empty array will produce a return value of null.
max_by Returns the highest found element using a custom expression to compute the associated value for each element in the input array.
merge Meges a list of objects together and returns the result.
min Returns the lowest found element in the provided array argument.
min_by Returns the lowest found element using a custom expression to compute the associated value for each element in the input array.
not_null Returns the first non null element in the input array.
pad_left Adds characters to the beginning of a string.
pad_right Adds characters to the end of a string.
replace Returns a copy of the input string with instances of old string argument replaced by new string argument.
reverse Reverses the input string or array and returns the result.
sort This function accepts an array argument and returns the sorted elements as an array.
sort_by This function accepts an array argument and returns the sorted elements as an array using a custom expression to compute the associated value for each element.
split Slices input string into substrings separated by a string argument and returns an array of the substrings between those separators.
starts_with Reports whether the input string begins with the provided string prefix argument.
sum Returns the sum of all numbers contained in the provided array.
to_array Returns a one element array containing the passed in argument, or the passed in value if it's an array.
to_number Returns the parsed number.
to_string The JSON encoded value of the given argument.
trim Removes the leading and trailing characters found in the passed in string argument.
trim_left Removes the leading characters found in the passed in string argument.
trim_right Removes the trailing characters found in the passed in string argument.
type Returns the JavaScript type of the given argument as a string value.
upper Returns the given string with all Unicode letters mapped to their upper case.
values Returns the values of the provided object.
zip Accepts one or more arrays as arguments and returns an array of arrays in which the i-th array contains the i-th element from each of the argument arrays. The returned array is truncated to the length of the shortest argument array.

kyverno-json functions

Name Description
at Returns the element in an array at the given index.
concat Concatenates two strings together and returns the result.
json_parse Parses a given JSON string into an object.
wildcard Compares a wildcard pattern with a given string and returns if they match or not.

kyverno functions

Name Description
compare Compares two strings lexicographically.
equal_fold Allows comparing two strings for equivalency where the only differences are letter cases.
replace Replaces a specified number of instances of the source string with the replacement string in a parent.
replace_all Replace all instances of one string with another in an overall parent string.
to_upper Takes in a string and outputs the same string with all upper-case letters.
to_lower Takes in a string and outputs the same string with all lower-case letters.
trim Trims both ends of the source string by characters appearing in the second string.
trim_prefix Trims the second string prefix from the first string if the first string starts with the prefix.
split Splits the first string when the second string is found and converts it into an array.
regex_replace_all Converts all parameters to string.
regex_replace_all_literal Converts all parameters to string.
regex_match First string is the regular exression which is compared with second input which can be a number or string.
pattern_match '*' matches zero or more alphanumeric characters, '?' matches a single alphanumeric character.
label_match Object arguments must be enclosed in backticks; ex. {{request.object.spec.template.metadata.labels}}.
to_boolean It returns true or false for any string, such as 'True', 'TruE', 'False', 'FAlse', 'faLSE', etc.
add Does arithmetic addition of two specified values of numbers, quantities, and durations.
sum Does arithmetic addition of specified array of values of numbers, quantities, and durations.
subtract Does arithmetic subtraction of two specified values of numbers, quantities, and durations.
multiply Does arithmetic multiplication of two specified values of numbers, quantities, and durations.
divide Divisor must be non zero.
modulo Divisor must be non-zero, arguments must be integers.
round Does roundoff to upto the given decimal places.
base64_decode Decodes a base 64 string.
base64_encode Encodes a regular, plaintext and unencoded string to base64.
time_since Calculate the difference between a start and end period of time where the end may either be a static definition or the then-current time.
time_now Returns current time in RFC 3339 format.
time_now_utc Returns current UTC time in RFC 3339 format.
path_canonicalize Normalizes or canonicalizes a given path by removing excess slashes.
truncate Length argument must be enclosed in backticks; ex. "{{request.object.metadata.name
semver_compare Compares two strings which comply with the semantic versioning schema and outputs a boolean response as to the position of the second relative to the first.
parse_json Decodes a valid JSON encoded string to the appropriate type. Opposite of to_string function.
parse_yaml Decodes a valid YAML encoded string to the appropriate type provided it can be represented as JSON.
lookup Returns the value corresponding to the given key/index in the given object/array.
items Converts a map or array to an array of objects where each key:value is an item in the array.
object_from_lists Converts a pair of lists containing keys and values to an object.
random Generates a random sequence of characters.
x509_decode Decodes an x.509 certificate to an object. you may also use this in conjunction with base64_decode jmespath function to decode a base64-encoded certificate.
time_to_cron Converts a time (RFC 3339) to a cron expression (string).
time_add Adds duration (second string) to a time value (first string).
time_parse Changes a time value of a given layout to RFC 3339.
time_utc Calcutes time in UTC from a given time in RFC 3339 format.
time_diff Calculate the difference between a start and end date in RFC3339 format.
time_before Checks if a time is before another time, both in RFC3339 format.
time_after Checks if a time is after another time, both in RFC3339 format.
time_between Checks if a time is between a start and end time, all in RFC3339 format.
time_truncate Returns the result of rounding time down to a multiple of duration.

chainsaw functions

Name Description
env Returns the value of the environment variable passed in argument.
x_k8s_get Gets a resource from a Kubernetes cluster.
x_k8s_list Lists resources from a Kubernetes cluster.
x_k8s_exists Checks if a given resource exists in a Kubernetes cluster.
x_k8s_resource_exists Checks if a given resource type is available in a Kubernetes cluster.
x_k8s_server_version Returns the version of a Kubernetes cluster.
x_metrics_decode Decodes metrics in the Prometheus text format.
trim_space Trims leading and trailing spaces from the string passed in argument.
as_string Returns the passed in argument converted into a string.
\ No newline at end of file + Functions - Chainsaw
Skip to content

Functions

Experimental functions

Experimental functions are denoted by the x_ prefix.

These are functions that are subject to signature change in a future version.

built-in functions

Name Description
abs Returns the absolute value of the provided argument.
avg Returns the average of the elements in the provided array. An empty array will produce a return value of null.
ceil Returns the next highest integer value by rounding up if necessary.
contains Returns true if the given subject contains the provided search value. If the subject is an array, this function returns true if one of the elements in the array is equal to the provided search value. If the provided subject is a string, this function returns true if the string contains the provided search argument.
ends_with Reports whether the given string ends with the provided suffix argument.
find_first Returns the zero-based index of the first occurence where the substring appears in a string or null if it does not appear.
find_last Returns the zero-based index of the last occurence where the substring appears in a string or null if it does not appear.
floor Returns the next lowest integer value by rounding down if necessary.
from_items Returns an object from the provided array of key value pairs. This function is the inversed of the items() function.
group_by Groups an array of objects using an expression as the group key.
items Converts a given object into an array of key-value pairs.
join Returns all of the elements from the provided array joined together using the glue argument as a separator between each.
keys Returns an array containing the keys of the provided object.
length Returns the length of the given argument. If the argument is a string this function returns the number of code points in the string. If the argument is an array this function returns the number of elements in the array. If the argument is an object this function returns the number of key-value pairs in the object.
lower Returns the given string with all Unicode letters mapped to their lower case.
map Transforms elements in a given array and returns the result.
max Returns the highest found element in the provided array argument. An empty array will produce a return value of null.
max_by Returns the highest found element using a custom expression to compute the associated value for each element in the input array.
merge Meges a list of objects together and returns the result.
min Returns the lowest found element in the provided array argument.
min_by Returns the lowest found element using a custom expression to compute the associated value for each element in the input array.
not_null Returns the first non null element in the input array.
pad_left Adds characters to the beginning of a string.
pad_right Adds characters to the end of a string.
replace Returns a copy of the input string with instances of old string argument replaced by new string argument.
reverse Reverses the input string or array and returns the result.
sort This function accepts an array argument and returns the sorted elements as an array.
sort_by This function accepts an array argument and returns the sorted elements as an array using a custom expression to compute the associated value for each element.
split Slices input string into substrings separated by a string argument and returns an array of the substrings between those separators.
starts_with Reports whether the input string begins with the provided string prefix argument.
sum Returns the sum of all numbers contained in the provided array.
to_array Returns a one element array containing the passed in argument, or the passed in value if it's an array.
to_number Returns the parsed number.
to_string The JSON encoded value of the given argument.
trim Removes the leading and trailing characters found in the passed in string argument.
trim_left Removes the leading characters found in the passed in string argument.
trim_right Removes the trailing characters found in the passed in string argument.
type Returns the JavaScript type of the given argument as a string value.
upper Returns the given string with all Unicode letters mapped to their upper case.
values Returns the values of the provided object.
zip Accepts one or more arrays as arguments and returns an array of arrays in which the i-th array contains the i-th element from each of the argument arrays. The returned array is truncated to the length of the shortest argument array.

kyverno-json functions

Name Description
at Returns the element in an array at the given index.
concat Concatenates two strings together and returns the result.
json_parse Parses a given JSON string into an object.
wildcard Compares a wildcard pattern with a given string and returns if they match or not.

kyverno functions

Name Description
compare Compares two strings lexicographically.
equal_fold Allows comparing two strings for equivalency where the only differences are letter cases.
replace Replaces a specified number of instances of the source string with the replacement string in a parent.
replace_all Replace all instances of one string with another in an overall parent string.
to_upper Takes in a string and outputs the same string with all upper-case letters.
to_lower Takes in a string and outputs the same string with all lower-case letters.
trim Trims both ends of the source string by characters appearing in the second string.
trim_prefix Trims the second string prefix from the first string if the first string starts with the prefix.
split Splits the first string when the second string is found and converts it into an array.
regex_replace_all Converts all parameters to string.
regex_replace_all_literal Converts all parameters to string.
regex_match First string is the regular exression which is compared with second input which can be a number or string.
pattern_match '*' matches zero or more alphanumeric characters, '?' matches a single alphanumeric character.
label_match Object arguments must be enclosed in backticks; ex. {{request.object.spec.template.metadata.labels}}.
to_boolean It returns true or false for any string, such as 'True', 'TruE', 'False', 'FAlse', 'faLSE', etc.
add Does arithmetic addition of two specified values of numbers, quantities, and durations.
sum Does arithmetic addition of specified array of values of numbers, quantities, and durations.
subtract Does arithmetic subtraction of two specified values of numbers, quantities, and durations.
multiply Does arithmetic multiplication of two specified values of numbers, quantities, and durations.
divide Divisor must be non zero.
modulo Divisor must be non-zero, arguments must be integers.
round Does roundoff to upto the given decimal places.
base64_decode Decodes a base 64 string.
base64_encode Encodes a regular, plaintext and unencoded string to base64.
time_since Calculate the difference between a start and end period of time where the end may either be a static definition or the then-current time.
time_now Returns current time in RFC 3339 format.
time_now_utc Returns current UTC time in RFC 3339 format.
path_canonicalize Normalizes or canonicalizes a given path by removing excess slashes.
truncate Length argument must be enclosed in backticks; ex. "{{request.object.metadata.name
semver_compare Compares two strings which comply with the semantic versioning schema and outputs a boolean response as to the position of the second relative to the first.
parse_json Decodes a valid JSON encoded string to the appropriate type. Opposite of to_string function.
parse_yaml Decodes a valid YAML encoded string to the appropriate type provided it can be represented as JSON.
lookup Returns the value corresponding to the given key/index in the given object/array.
items Converts a map or array to an array of objects where each key:value is an item in the array.
object_from_lists Converts a pair of lists containing keys and values to an object.
random Generates a random sequence of characters.
x509_decode Decodes an x.509 certificate to an object. you may also use this in conjunction with base64_decode jmespath function to decode a base64-encoded certificate.
time_to_cron Converts a time (RFC 3339) to a cron expression (string).
time_add Adds duration (second string) to a time value (first string).
time_parse Changes a time value of a given layout to RFC 3339.
time_utc Calcutes time in UTC from a given time in RFC 3339 format.
time_diff Calculate the difference between a start and end date in RFC3339 format.
time_before Checks if a time is before another time, both in RFC3339 format.
time_after Checks if a time is after another time, both in RFC3339 format.
time_between Checks if a time is between a start and end time, all in RFC3339 format.
time_truncate Returns the result of rounding time down to a multiple of duration.

chainsaw functions

Name Description
env Returns the value of the environment variable passed in argument.
x_k8s_get Gets a resource from a Kubernetes cluster.
x_k8s_list Lists resources from a Kubernetes cluster.
x_k8s_exists Checks if a given resource exists in a Kubernetes cluster.
x_k8s_resource_exists Checks if a given resource type is available in a Kubernetes cluster.
x_k8s_server_version Returns the version of a Kubernetes cluster.
x_metrics_decode Decodes metrics in the Prometheus text format.
trim_space Trims leading and trailing spaces from the string passed in argument.
as_string Returns the passed in argument converted into a string.
\ No newline at end of file diff --git a/main/reference/json-schemas/index.html b/main/reference/json-schemas/index.html index a46212771..5b00d7337 100644 --- a/main/reference/json-schemas/index.html +++ b/main/reference/json-schemas/index.html @@ -1,4 +1,4 @@ - JSON schemas - Chainsaw
Skip to content

JSON schemas

JSON schemas for Chainsaw are available:

They can be used to enable validation and autocompletion in your IDE.

VS code

In VS code, simply add a comment on top of your YAML resources.

Test

# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
+ JSON schemas - Chainsaw      

JSON schemas

JSON schemas for Chainsaw are available:

They can be used to enable validation and autocompletion in your IDE.

VS code

In VS code, simply add a comment on top of your YAML resources.

Test

# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
 apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
@@ -29,4 +29,4 @@
     failFast: true
     parallel: 4
 

Exporting schemas

Chainsaw can also export JSON schemas locally if you don't want to reference them from GitHub:

chainsaw export schemas <local path>
-

See chainsaw export schemas command documentation for more details.

\ No newline at end of file +

See chainsaw export schemas command documentation for more details.

\ No newline at end of file diff --git a/main/sitemap.xml b/main/sitemap.xml index 6752b72cf..2df16a4a4 100644 --- a/main/sitemap.xml +++ b/main/sitemap.xml @@ -2,846 +2,846 @@ https://kyverno.github.io/chainsaw/main/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/cicd/gh-action/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/community/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/community/contribute/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/community/making-a-pull-request/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/community/reporting-a-bug/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/community/reporting-a-docs-issue/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/community/requesting-a-change/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/file/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/flags/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/cleanup/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/clusters/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/deletion/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/discovery/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/error/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/execution/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/label-selectors/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/namespace/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/no-cluster/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/pause/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/report/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/templating/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/timeouts/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/configuration/options/values/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/concurrency/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/crds/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/events/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/inline/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/kube-version/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/label-selectors/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/multi-cluster/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/negative-testing/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/non-resource-assertions/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/test-output/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/examples/values/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/general/bindings/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/general/checks/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/general/inheritance/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/general/namespace/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/general/outputs/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/general/references/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/general/templating/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/guides/kuttl-migration/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/guides/lint/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/guides/test-docs/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/apply/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/assert/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/command/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/create/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/delete/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/error/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/patch/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/script/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/sleep/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/update/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/helpers/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/helpers/describe/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/helpers/events/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/helpers/get/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/helpers/logs/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/operations/helpers/wait/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/assertion-trees/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/bindings/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/cleanup/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/completion/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/first-test/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/install/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/next-steps/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/operation-outputs/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/resource-templating/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/resources/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/run-tests/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/timeouts/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/quick-start/try-catch/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/builtins/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/json-schemas/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/apis/chainsaw.v1alpha1/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/apis/chainsaw.v1alpha2/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_assert/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_build/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_build_docs/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_completion/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_completion_bash/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_completion_fish/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_completion_powershell/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_completion_zsh/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_create/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_create_test/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_docs/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_export/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_export_schemas/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_lint/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_migrate/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_migrate_kuttl/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_migrate_kuttl_config/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_migrate_kuttl_tests/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_renovate/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_renovate_config/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_test/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/commands/chainsaw_version/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/functions/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/abs/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/add/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/as_string/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/at/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/avg/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/base64_decode/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/base64_encode/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/ceil/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/compare/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/concat/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/contains/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/divide/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/ends_with/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/env/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/equal_fold/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/find_first/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/find_last/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/floor/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/from_items/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/group_by/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/items/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/join/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/json_parse/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/keys/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/label_match/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/length/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/lookup/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/lower/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/map/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/max/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/max_by/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/merge/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/min/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/min_by/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/modulo/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/multiply/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/not_null/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/object_from_lists/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/pad_left/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/pad_right/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/parse_json/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/parse_yaml/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/path_canonicalize/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/pattern_match/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/random/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/regex_match/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/regex_replace_all/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/regex_replace_all_literal/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/replace/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/replace_all/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/reverse/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/round/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/semver_compare/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/sort/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/sort_by/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/split/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/starts_with/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/subtract/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/sum/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_add/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_after/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_before/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_between/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_diff/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_now/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_now_utc/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_parse/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_since/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_to_cron/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_truncate/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/time_utc/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/to_array/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/to_boolean/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/to_lower/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/to_number/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/to_string/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/to_upper/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/trim/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/trim_left/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/trim_prefix/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/trim_right/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/trim_space/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/truncate/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/type/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/upper/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/values/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/wildcard/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/x509_decode/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/x_k8s_exists/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/x_k8s_get/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/x_k8s_list/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/x_k8s_resource_exists/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/x_k8s_server_version/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/x_metrics_decode/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/reference/jp/examples/zip/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/step/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/step/catch/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/step/cleanup/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/step/finally/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/step/try/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/test/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/test/conventional/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/test/explicit/ - 2024-11-20 + 2024-12-03 https://kyverno.github.io/chainsaw/main/test/spec/ - 2024-11-20 + 2024-12-03 \ No newline at end of file diff --git a/main/sitemap.xml.gz b/main/sitemap.xml.gz index 501ca0ff5..a9b320749 100644 Binary files a/main/sitemap.xml.gz and b/main/sitemap.xml.gz differ diff --git a/main/step/catch/index.html b/main/step/catch/index.html index 9be572576..62856ce7c 100644 --- a/main/step/catch/index.html +++ b/main/step/catch/index.html @@ -1 +1 @@ - catch - Chainsaw
Skip to content

catch

A catch statement is also a sequence of operations.

Operations contained in a catch statement will be executed only if the step failed when executing the operations in the step's try statement.

Tip

All operations of a catch statement will be executed regardless of the success or failure of each of them.

Operations

A catch statement supports only the following operations:

Inheritance

Under certain circumstances, it can be useful to configure catch blocks at a higher level than the step grain. At the test or configuration level.

This allows for declaring common catch statements we want to execute when an error occurs. Those catch blocks are combined to produce the final catch block in the following order:

  1. catch statements from the configuration level are executed first (if any)
  2. catch statements from the test level are executed next (if any)
  3. catch statements from the step level are executed last (if any)
\ No newline at end of file + catch - Chainsaw
Skip to content

catch

A catch statement is also a sequence of operations.

Operations contained in a catch statement will be executed only if the step failed when executing the operations in the step's try statement.

Tip

All operations of a catch statement will be executed regardless of the success or failure of each of them.

Operations

A catch statement supports only the following operations:

Inheritance

Under certain circumstances, it can be useful to configure catch blocks at a higher level than the step grain. At the test or configuration level.

This allows for declaring common catch statements we want to execute when an error occurs. Those catch blocks are combined to produce the final catch block in the following order:

  1. catch statements from the configuration level are executed first (if any)
  2. catch statements from the test level are executed next (if any)
  3. catch statements from the step level are executed last (if any)
\ No newline at end of file diff --git a/main/step/cleanup/index.html b/main/step/cleanup/index.html index 79b2fcdc3..ab7923ff1 100644 --- a/main/step/cleanup/index.html +++ b/main/step/cleanup/index.html @@ -1 +1 @@ - cleanup - Chainsaw
Skip to content

cleanup

A cleanup statement is similar to a finally statement but will execute after the test finishes executing, while finally executes after the step finishes executing.

Tip

All operations of a cleanup statement will be executed regardless of the success or failure of each of them.

Operations

A cleanup statement supports only the following operations:

\ No newline at end of file + cleanup - Chainsaw
Skip to content

cleanup

A cleanup statement is similar to a finally statement but will execute after the test finishes executing, while finally executes after the step finishes executing.

Tip

All operations of a cleanup statement will be executed regardless of the success or failure of each of them.

Operations

A cleanup statement supports only the following operations:

\ No newline at end of file diff --git a/main/step/finally/index.html b/main/step/finally/index.html index 8de232f89..2d1b17644 100644 --- a/main/step/finally/index.html +++ b/main/step/finally/index.html @@ -1 +1 @@ - finally - Chainsaw
Skip to content

finally

A finally statement is similar to a catch statement but will always execute after the try and eventual catch statements finished executing regardless of the success or failure of the test step.

Tip

All operations of a finally statement will be executed regardless of the success or failure of each of them.

Operations

A finally statement supports only the following operations:

\ No newline at end of file + finally - Chainsaw
Skip to content

finally

A finally statement is similar to a catch statement but will always execute after the try and eventual catch statements finished executing regardless of the success or failure of the test step.

Tip

All operations of a finally statement will be executed regardless of the success or failure of each of them.

Operations

A finally statement supports only the following operations:

\ No newline at end of file diff --git a/main/step/index.html b/main/step/index.html index 16ebcef3b..52710e4dc 100644 --- a/main/step/index.html +++ b/main/step/index.html @@ -1,4 +1,4 @@ - What is a test step? - Chainsaw
Skip to content

What is a test step?

A test step is made of four main components used to determine the actions Chainsaw will perform when executing the step.

  1. The try statement (required)
  2. The catch statement (optional)
  3. The finally statement (optional)
  4. The cleanup statement (optional)

Syntax

apiVersion: chainsaw.kyverno.io/v1alpha1
+ What is a test step? - Chainsaw      

What is a test step?

A test step is made of four main components used to determine the actions Chainsaw will perform when executing the step.

  1. The try statement (required)
  2. The catch statement (optional)
  3. The finally statement (optional)
  4. The cleanup statement (optional)

Syntax

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -61,4 +61,4 @@
     C2 -->> S  : done
     S  -->> F1 : finally
     F1 ->>  F2 : done
-    F2 -->> S  : done
  1. Step starts by executing operations in the try block
  2. Operations in the try block execute sequentially until an error happens
  3. Operations in the try block stop when an error occurs
  4. Step starts executing operations in the catch block
  5. Operations in the catch block execute sequentially
  6. All operations in the catch block terminate
  7. Step starts executing operations in the finally block
  8. Operations in the finally block execute sequentially
  9. All operations in the finally block terminate

Cleanup

In addition to try, catch and finally blocks, the cleanup block of steps is better illustrated in the Test lifecycle diagrams.

\ No newline at end of file + F2 -->> S : done
  1. Step starts by executing operations in the try block
  2. Operations in the try block execute sequentially until an error happens
  3. Operations in the try block stop when an error occurs
  4. Step starts executing operations in the catch block
  5. Operations in the catch block execute sequentially
  6. All operations in the catch block terminate
  7. Step starts executing operations in the finally block
  8. Operations in the finally block execute sequentially
  9. All operations in the finally block terminate

Cleanup

In addition to try, catch and finally blocks, the cleanup block of steps is better illustrated in the Test lifecycle diagrams.

\ No newline at end of file diff --git a/main/step/try/index.html b/main/step/try/index.html index 8c81e48f1..8727c329c 100644 --- a/main/step/try/index.html +++ b/main/step/try/index.html @@ -1 +1 @@ - try - Chainsaw
Skip to content
\ No newline at end of file + try - Chainsaw
Skip to content
\ No newline at end of file diff --git a/main/test/conventional/index.html b/main/test/conventional/index.html index aca30999b..207fdce7c 100644 --- a/main/test/conventional/index.html +++ b/main/test/conventional/index.html @@ -1,4 +1,4 @@ - Conventional approach - Chainsaw
Skip to content

Conventional approach

Warning

While Chainsaw supports the conventional approach, we strongly recommend the explicit one.

If you are new to Chainsaw we suggest you skip this section and jump directly to the Explicit approach.

Introduction

The conventional approach is the simplest and less verbose one.

You provide bare Kubernetes resource manifests and Chainsaw will use those manifests to create, update, or assert expectations against a cluster.

Limitations

While this syntax is simple, it suffers lots of limitations. It doesn't support deletion operations, commands, scripts, and all Chainsaw helpers.

It is also impossible to specify additional configuration per test, step or individual operation (timeouts, additional verifications, etc...), making this approach highly limited.

It also relies a lot on file naming conventions which can be error prone.

Finally, this approach doesn't encourage reusing files across tests and leads to duplication, making maintenance harder.

File naming convention

Manifest files must follow a specific naming convention:

<step index>-<name|assert|errors>.yaml
+ Conventional approach - Chainsaw      

Conventional approach

Warning

While Chainsaw supports the conventional approach, we strongly recommend the explicit one.

If you are new to Chainsaw we suggest you skip this section and jump directly to the Explicit approach.

Introduction

The conventional approach is the simplest and less verbose one.

You provide bare Kubernetes resource manifests and Chainsaw will use those manifests to create, update, or assert expectations against a cluster.

Limitations

While this syntax is simple, it suffers lots of limitations. It doesn't support deletion operations, commands, scripts, and all Chainsaw helpers.

It is also impossible to specify additional configuration per test, step or individual operation (timeouts, additional verifications, etc...), making this approach highly limited.

It also relies a lot on file naming conventions which can be error prone.

Finally, this approach doesn't encourage reusing files across tests and leads to duplication, making maintenance harder.

File naming convention

Manifest files must follow a specific naming convention:

<step index>-<name|assert|errors>.yaml
 

As an example, 00-configmap.yaml, 01-assert.yaml and 02-errors.yaml are valid file names.

Assembling steps

It's perfectly valid to have multiple files for the same step.

Let's say we have the following files 00-resources.yaml, 00-more-resources.yaml, 00-assert.yaml and 00-errors.yaml:

  • 00-resources.yaml and 00-more-resources.yaml contain resources that will be applied in step 00
  • 00-assert.yaml contains assert statements in step 00
  • 00-errors.yaml contains error statements in step 00

With the four files above, Chainsaw will assemble a test step made of the combination of all those files.

Loading process

The logic to determine the content of a step is always:

  • The step index is obtained from the beginning of the file name, it must be composed of two numbers between 0 and 9 (from 00 to 99)
  • The next character acts as a separator and is expected to be -
  • The rest of the file name (without extension) is then evaluated
    • If it is equal to assert, the content is considered assertion statements
    • If it is equal to error, the content is considered error statements
    • Else the content is considered resources to be applied
  • The extension must be .yaml or .yml

Example

01-configmap.yaml

The manifest below contains a config map in a file called 01-configmap.yaml. Chainsaw will associate this manifest with an apply operation in step 01.

apiVersion: v1
 kind: ConfigMap
 metadata:
@@ -17,4 +17,4 @@
   name: chainsaw-quick-start
 data:
   lorem: ipsum
-

Conclusion

This test will first create a config map, then assert the content of the config map contains the foo: bar data, and then verify that the config map does not contain the lorem: ipsum data.

For such a simple test, the conventional approach works reasonably well but will quickly become limited when the test scenarios get more complex.

Look at the explicit approach for a lot more flexible solution.

\ No newline at end of file +

Conclusion

This test will first create a config map, then assert the content of the config map contains the foo: bar data, and then verify that the config map does not contain the lorem: ipsum data.

For such a simple test, the conventional approach works reasonably well but will quickly become limited when the test scenarios get more complex.

Look at the explicit approach for a lot more flexible solution.

\ No newline at end of file diff --git a/main/test/explicit/index.html b/main/test/explicit/index.html index b0a0b7588..7334ecb78 100644 --- a/main/test/explicit/index.html +++ b/main/test/explicit/index.html @@ -1,4 +1,4 @@ - Explicit approach - Chainsaw
Skip to content

Explicit approach

The explicit is a bit more verbose than the conventional one but offers far more flexibility and features:

  • It does not rely on file naming conventions for operations ordering
  • It encourages file reuse across tests, reducing duplication and maintenance
  • It offers the flexibility to provide additional configurations like timeouts, complex logic, etc...
  • It supports all operations without restrictions

The Test resource

A Test resource, like any other Kubernetes resource, has an apiVersion, kind and metadata section.

It also comes with a spec section used to declaratively represent the test logic, steps and operations, as well as other configuration elements belonging to the test being defined.

Reference documentation

The full structure of the Test resource is documented here.

Example

chainsaw-test.yaml

The Test below illustrates a simple test. Chainsaw will load the Test and steps defined in its spec section.

It's worth noting that:

  • The test defines its own timeouts
  • It also states that this test should not be executed in parallel with other tests
  • It has multiple steps, most of them reference files that can be used in other tests if needed
  • It uses an arbitrary shell script
apiVersion: chainsaw.kyverno.io/v1alpha1
+ Explicit approach - Chainsaw      

Explicit approach

The explicit is a bit more verbose than the conventional one but offers far more flexibility and features:

  • It does not rely on file naming conventions for operations ordering
  • It encourages file reuse across tests, reducing duplication and maintenance
  • It offers the flexibility to provide additional configurations like timeouts, complex logic, etc...
  • It supports all operations without restrictions

The Test resource

A Test resource, like any other Kubernetes resource, has an apiVersion, kind and metadata section.

It also comes with a spec section used to declaratively represent the test logic, steps and operations, as well as other configuration elements belonging to the test being defined.

Reference documentation

The full structure of the Test resource is documented here.

Example

chainsaw-test.yaml

The Test below illustrates a simple test. Chainsaw will load the Test and steps defined in its spec section.

It's worth noting that:

  • The test defines its own timeouts
  • It also states that this test should not be executed in parallel with other tests
  • It has multiple steps, most of them reference files that can be used in other tests if needed
  • It uses an arbitrary shell script
apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -36,4 +36,4 @@
   - try:
     - script:
         content: echo "goodbye"
-

Conclusion

While this test is simple, it illustrates the differences with the conventional approach.

The purpose here is only to present the explicit approach and there are a lot more features to discuss, we will cover them in the next sections.

\ No newline at end of file +

Conclusion

While this test is simple, it illustrates the differences with the conventional approach.

The purpose here is only to present the explicit approach and there are a lot more features to discuss, we will cover them in the next sections.

\ No newline at end of file diff --git a/main/test/index.html b/main/test/index.html index c2ca39107..14fcdb8ea 100644 --- a/main/test/index.html +++ b/main/test/index.html @@ -1 +1 @@ - Writing Chainsaw tests - Chainsaw
Skip to content

Writing Chainsaw tests

This documentation focuses on providing a breakdown of the Chainsaw test structure and how to use it.

What is a test?

To put it simply, a test can be represented as an ordered sequence of test steps.

In turn, a test step can be represented as an ordered sequence of operations.

  • When an operation fails the test is considered failed
  • If all operations succeed the test is considered successful

Definition approach

Chainsaw supports two different test definition approaches:

Tip

While Chainsaw supports two test definition approaches, we strongly recommend the explicit one.

General concepts

The concepts below are at the heart of Chainsaw:

Test and Step specs

Browse the test and step specs to learn all the details and options:

\ No newline at end of file + Writing Chainsaw tests - Chainsaw
Skip to content

Writing Chainsaw tests

This documentation focuses on providing a breakdown of the Chainsaw test structure and how to use it.

What is a test?

To put it simply, a test can be represented as an ordered sequence of test steps.

In turn, a test step can be represented as an ordered sequence of operations.

  • When an operation fails the test is considered failed
  • If all operations succeed the test is considered successful

Definition approach

Chainsaw supports two different test definition approaches:

Tip

While Chainsaw supports two test definition approaches, we strongly recommend the explicit one.

General concepts

The concepts below are at the heart of Chainsaw:

Test and Step specs

Browse the test and step specs to learn all the details and options:

\ No newline at end of file diff --git a/main/test/spec/index.html b/main/test/spec/index.html index 60910fb45..5876805b5 100644 --- a/main/test/spec/index.html +++ b/main/test/spec/index.html @@ -1,4 +1,4 @@ - Test spec - Chainsaw
Skip to content

Test spec

A Chainsaw test is mostly made of steps.

That being said, there are a couple of other interesting fields too.

Syntax

apiVersion: chainsaw.kyverno.io/v1alpha1
+ Test spec - Chainsaw      

Test spec

A Chainsaw test is mostly made of steps.

That being said, there are a couple of other interesting fields too.

Syntax

apiVersion: chainsaw.kyverno.io/v1alpha1
 kind: Test
 metadata:
   name: example
@@ -49,4 +49,4 @@
     Note left of S3: Step 3 is NOT executed
 
     S2 -->> S1: cleanup
-    S1 -->> T: cleanup
  1. Test starts by executing Step 1
  2. Step 1 terminates -> Step 2 starts executing
  3. Step 2 fails -> Cleanup for Step 2 starts
  4. Cleanup for Step 2 terminates -> Cleanup for Step 1 is executed

Supported elements

Namespace

The namespace the test should run into, see Namespace selection.

Namespace template

Eventually provide a template if you something specific, see Namespace template.

Timeouts

All timeouts can be specified per test, see Control your timeouts.

Clusters

Additional clusters can be registered at the test level, see Multi-cluster options.

Cluster

The cluster (by name) used to run the test, see Multi-cluster setup.

Bindings

Bindings can be registered at the test level and inherited in all steps, see Bindings.

Catch

Catch blocks can be specified at the test level to declare common catch statements.

Template

Chainsaw allows templating configuration on a per test basis.

Concurrency

Controlling concurrency per test is also possible, see Concurrency control.

Skip

In case you need to skip a test for whatever reason, use skip: true.

Steps

Steps are what tests will execute when they are run, see Test step spec dedicated section.

\ No newline at end of file + S1 -->> T: cleanup
  1. Test starts by executing Step 1
  2. Step 1 terminates -> Step 2 starts executing
  3. Step 2 fails -> Cleanup for Step 2 starts
  4. Cleanup for Step 2 terminates -> Cleanup for Step 1 is executed

Supported elements

Namespace

The namespace the test should run into, see Namespace selection.

Namespace template

Eventually provide a template if you something specific, see Namespace template.

Timeouts

All timeouts can be specified per test, see Control your timeouts.

Clusters

Additional clusters can be registered at the test level, see Multi-cluster options.

Cluster

The cluster (by name) used to run the test, see Multi-cluster setup.

Bindings

Bindings can be registered at the test level and inherited in all steps, see Bindings.

Catch

Catch blocks can be specified at the test level to declare common catch statements.

Template

Chainsaw allows templating configuration on a per test basis.

Concurrency

Controlling concurrency per test is also possible, see Concurrency control.

Skip

In case you need to skip a test for whatever reason, use skip: true.

Steps

Steps are what tests will execute when they are run, see Test step spec dedicated section.

\ No newline at end of file