diff --git a/404.html b/404.html index f2083d0df..2fc962146 100644 --- a/404.html +++ b/404.html @@ -9,7 +9,7 @@ - + @@ -17,10 +17,10 @@ - + - + @@ -2425,7 +2425,7 @@ - + diff --git a/assets/javascripts/bundle.748e2769.min.js b/assets/javascripts/bundle.748e2769.min.js deleted file mode 100644 index c0275d252..000000000 --- a/assets/javascripts/bundle.748e2769.min.js +++ /dev/null @@ -1,29 +0,0 @@ -(()=>{var ea=Object.create;var gr=Object.defineProperty;var ta=Object.getOwnPropertyDescriptor;var ra=Object.getOwnPropertyNames,At=Object.getOwnPropertySymbols,na=Object.getPrototypeOf,yr=Object.prototype.hasOwnProperty,nn=Object.prototype.propertyIsEnumerable;var rn=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,I=(e,t)=>{for(var r in t||(t={}))yr.call(t,r)&&rn(e,r,t[r]);if(At)for(var r of At(t))nn.call(t,r)&&rn(e,r,t[r]);return e};var on=(e,t)=>{var r={};for(var n in e)yr.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&At)for(var n of At(e))t.indexOf(n)<0&&nn.call(e,n)&&(r[n]=e[n]);return r};var bt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var oa=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ra(t))!yr.call(e,o)&&o!==r&&gr(e,o,{get:()=>t[o],enumerable:!(n=ta(t,o))||n.enumerable});return e};var Qe=(e,t,r)=>(r=e!=null?ea(na(e)):{},oa(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var sn=bt((xr,an)=>{(function(e,t){typeof xr=="object"&&typeof an!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(O){return!!(O&&O!==document&&O.nodeName!=="HTML"&&O.nodeName!=="BODY"&&"classList"in O&&"contains"in O.classList)}function c(O){var je=O.type,de=O.tagName;return!!(de==="INPUT"&&a[je]&&!O.readOnly||de==="TEXTAREA"&&!O.readOnly||O.isContentEditable)}function u(O){O.classList.contains("focus-visible")||(O.classList.add("focus-visible"),O.setAttribute("data-focus-visible-added",""))}function f(O){!O.hasAttribute("data-focus-visible-added")||(O.classList.remove("focus-visible"),O.removeAttribute("data-focus-visible-added"))}function p(O){O.metaKey||O.altKey||O.ctrlKey||(s(r.activeElement)&&u(r.activeElement),n=!0)}function l(O){n=!1}function d(O){!s(O.target)||(n||c(O.target))&&u(O.target)}function h(O){!s(O.target)||(O.target.classList.contains("focus-visible")||O.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),f(O.target))}function b(O){document.visibilityState==="hidden"&&(o&&(n=!0),F())}function F(){document.addEventListener("mousemove",U),document.addEventListener("mousedown",U),document.addEventListener("mouseup",U),document.addEventListener("pointermove",U),document.addEventListener("pointerdown",U),document.addEventListener("pointerup",U),document.addEventListener("touchmove",U),document.addEventListener("touchstart",U),document.addEventListener("touchend",U)}function K(){document.removeEventListener("mousemove",U),document.removeEventListener("mousedown",U),document.removeEventListener("mouseup",U),document.removeEventListener("pointermove",U),document.removeEventListener("pointerdown",U),document.removeEventListener("pointerup",U),document.removeEventListener("touchmove",U),document.removeEventListener("touchstart",U),document.removeEventListener("touchend",U)}function U(O){O.target.nodeName&&O.target.nodeName.toLowerCase()==="html"||(n=!1,K())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",l,!0),document.addEventListener("pointerdown",l,!0),document.addEventListener("touchstart",l,!0),document.addEventListener("visibilitychange",b,!0),F(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var cn=bt(Sr=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(u){return!1}},r=t(),n=function(u){var f={next:function(){var p=u.shift();return{done:p===void 0,value:p}}};return r&&(f[Symbol.iterator]=function(){return f}),f},o=function(u){return encodeURIComponent(u).replace(/%20/g,"+")},i=function(u){return decodeURIComponent(String(u).replace(/\+/g," "))},a=function(){var u=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var l=typeof p;if(l!=="undefined")if(l==="string")p!==""&&this._fromString(p);else if(p instanceof u){var d=this;p.forEach(function(K,U){d.append(U,K)})}else if(p!==null&&l==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),u._entries&&(u._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(c,u){typeof c!="string"&&(c=String(c)),u&&typeof u!="string"&&(u=String(u));var f=document,p;if(u&&(e.location===void 0||u!==e.location.href)){u=u.toLowerCase(),f=document.implementation.createHTMLDocument(""),p=f.createElement("base"),p.href=u,f.head.appendChild(p);try{if(p.href.indexOf(u)!==0)throw new Error(p.href)}catch(O){throw new Error("URL unable to set base "+u+" due to "+O)}}var l=f.createElement("a");l.href=c,p&&(f.body.appendChild(l),l.href=l.href);var d=f.createElement("input");if(d.type="url",d.value=c,l.protocol===":"||!/:/.test(l.href)||!d.checkValidity()&&!u)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:l});var h=new e.URLSearchParams(this.search),b=!0,F=!0,K=this;["append","delete","set"].forEach(function(O){var je=h[O];h[O]=function(){je.apply(h,arguments),b&&(F=!1,K.search=h.toString(),F=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var U=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==U&&(U=this.search,F&&(b=!1,this.searchParams._fromString(this.search),b=!0))}})},a=i.prototype,s=function(c){Object.defineProperty(a,c,{get:function(){return this._anchorElement[c]},set:function(u){this._anchorElement[c]=u},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(c){s(c)}),Object.defineProperty(a,"search",{get:function(){return this._anchorElement.search},set:function(c){this._anchorElement.search=c,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(a,{toString:{get:function(){var c=this;return function(){return c.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(c){this._anchorElement.href=c,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(c){this._anchorElement.pathname=c},enumerable:!0},origin:{get:function(){var c={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],u=this._anchorElement.port!=c&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(u?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(c){},enumerable:!0},username:{get:function(){return""},set:function(c){},enumerable:!0}}),i.createObjectURL=function(c){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(c){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr)});var An=bt((Fs,kt)=>{/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */var un,fn,pn,ln,mn,dn,hn,bn,vn,Ct,wr,gn,yn,xn,tt,Sn,wn,En,On,_n,Tn,Mn,Ln,Rt;(function(e){var t=typeof global=="object"?global:typeof self=="object"?self:typeof this=="object"?this:{};typeof define=="function"&&define.amd?define("tslib",["exports"],function(n){e(r(t,r(n)))}):typeof kt=="object"&&typeof kt.exports=="object"?e(r(t,r(kt.exports))):e(r(t));function r(n,o){return n!==t&&(typeof Object.create=="function"?Object.defineProperty(n,"__esModule",{value:!0}):n.__esModule=!0),function(i,a){return n[i]=o?o(i,a):a}}})(function(e){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])};un=function(n,o){if(typeof o!="function"&&o!==null)throw new TypeError("Class extends value "+String(o)+" is not a constructor or null");t(n,o);function i(){this.constructor=n}n.prototype=o===null?Object.create(o):(i.prototype=o.prototype,new i)},fn=Object.assign||function(n){for(var o,i=1,a=arguments.length;i=0;f--)(u=n[f])&&(c=(s<3?u(c):s>3?u(o,i,c):u(o,i))||c);return s>3&&c&&Object.defineProperty(o,i,c),c},mn=function(n,o){return function(i,a){o(i,a,n)}},dn=function(n,o){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(n,o)},hn=function(n,o,i,a){function s(c){return c instanceof i?c:new i(function(u){u(c)})}return new(i||(i=Promise))(function(c,u){function f(d){try{l(a.next(d))}catch(h){u(h)}}function p(d){try{l(a.throw(d))}catch(h){u(h)}}function l(d){d.done?c(d.value):s(d.value).then(f,p)}l((a=a.apply(n,o||[])).next())})},bn=function(n,o){var i={label:0,sent:function(){if(c[0]&1)throw c[1];return c[1]},trys:[],ops:[]},a,s,c,u;return u={next:f(0),throw:f(1),return:f(2)},typeof Symbol=="function"&&(u[Symbol.iterator]=function(){return this}),u;function f(l){return function(d){return p([l,d])}}function p(l){if(a)throw new TypeError("Generator is already executing.");for(;i;)try{if(a=1,s&&(c=l[0]&2?s.return:l[0]?s.throw||((c=s.return)&&c.call(s),0):s.next)&&!(c=c.call(s,l[1])).done)return c;switch(s=0,c&&(l=[l[0]&2,c.value]),l[0]){case 0:case 1:c=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,s=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(c=i.trys,!(c=c.length>0&&c[c.length-1])&&(l[0]===6||l[0]===2)){i=0;continue}if(l[0]===3&&(!c||l[1]>c[0]&&l[1]=n.length&&(n=void 0),{value:n&&n[a++],done:!n}}};throw new TypeError(o?"Object is not iterable.":"Symbol.iterator is not defined.")},wr=function(n,o){var i=typeof Symbol=="function"&&n[Symbol.iterator];if(!i)return n;var a=i.call(n),s,c=[],u;try{for(;(o===void 0||o-- >0)&&!(s=a.next()).done;)c.push(s.value)}catch(f){u={error:f}}finally{try{s&&!s.done&&(i=a.return)&&i.call(a)}finally{if(u)throw u.error}}return c},gn=function(){for(var n=[],o=0;o1||f(b,F)})})}function f(b,F){try{p(a[b](F))}catch(K){h(c[0][3],K)}}function p(b){b.value instanceof tt?Promise.resolve(b.value.v).then(l,d):h(c[0][2],b)}function l(b){f("next",b)}function d(b){f("throw",b)}function h(b,F){b(F),c.shift(),c.length&&f(c[0][0],c[0][1])}},wn=function(n){var o,i;return o={},a("next"),a("throw",function(s){throw s}),a("return"),o[Symbol.iterator]=function(){return this},o;function a(s,c){o[s]=n[s]?function(u){return(i=!i)?{value:tt(n[s](u)),done:s==="return"}:c?c(u):u}:c}},En=function(n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var o=n[Symbol.asyncIterator],i;return o?o.call(n):(n=typeof Ct=="function"?Ct(n):n[Symbol.iterator](),i={},a("next"),a("throw"),a("return"),i[Symbol.asyncIterator]=function(){return this},i);function a(c){i[c]=n[c]&&function(u){return new Promise(function(f,p){u=n[c](u),s(f,p,u.done,u.value)})}}function s(c,u,f,p){Promise.resolve(p).then(function(l){c({value:l,done:f})},u)}},On=function(n,o){return Object.defineProperty?Object.defineProperty(n,"raw",{value:o}):n.raw=o,n};var r=Object.create?function(n,o){Object.defineProperty(n,"default",{enumerable:!0,value:o})}:function(n,o){n.default=o};_n=function(n){if(n&&n.__esModule)return n;var o={};if(n!=null)for(var i in n)i!=="default"&&Object.prototype.hasOwnProperty.call(n,i)&&Rt(o,n,i);return r(o,n),o},Tn=function(n){return n&&n.__esModule?n:{default:n}},Mn=function(n,o,i,a){if(i==="a"&&!a)throw new TypeError("Private accessor was defined without a getter");if(typeof o=="function"?n!==o||!a:!o.has(n))throw new TypeError("Cannot read private member from an object whose class did not declare it");return i==="m"?a:i==="a"?a.call(n):a?a.value:o.get(n)},Ln=function(n,o,i,a,s){if(a==="m")throw new TypeError("Private method is not writable");if(a==="a"&&!s)throw new TypeError("Private accessor was defined without a setter");if(typeof o=="function"?n!==o||!s:!o.has(n))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a==="a"?s.call(n,i):s?s.value=i:o.set(n,i),i},e("__extends",un),e("__assign",fn),e("__rest",pn),e("__decorate",ln),e("__param",mn),e("__metadata",dn),e("__awaiter",hn),e("__generator",bn),e("__exportStar",vn),e("__createBinding",Rt),e("__values",Ct),e("__read",wr),e("__spread",gn),e("__spreadArrays",yn),e("__spreadArray",xn),e("__await",tt),e("__asyncGenerator",Sn),e("__asyncDelegator",wn),e("__asyncValues",En),e("__makeTemplateObject",On),e("__importStar",_n),e("__importDefault",Tn),e("__classPrivateFieldGet",Mn),e("__classPrivateFieldSet",Ln)})});var Qr=bt((_t,qr)=>{/*! - * clipboard.js v2.0.10 - * https://clipboardjs.com/ - * - * Licensed MIT © Zeno Rocha - */(function(t,r){typeof _t=="object"&&typeof qr=="object"?qr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof _t=="object"?_t.ClipboardJS=r():t.ClipboardJS=r()})(_t,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return Zi}});var a=i(279),s=i.n(a),c=i(370),u=i.n(c),f=i(817),p=i.n(f);function l(P){try{return document.execCommand(P)}catch(M){return!1}}var d=function(M){var w=p()(M);return l("cut"),w},h=d;function b(P){var M=document.documentElement.getAttribute("dir")==="rtl",w=document.createElement("textarea");w.style.fontSize="12pt",w.style.border="0",w.style.padding="0",w.style.margin="0",w.style.position="absolute",w.style[M?"right":"left"]="-9999px";var D=window.pageYOffset||document.documentElement.scrollTop;return w.style.top="".concat(D,"px"),w.setAttribute("readonly",""),w.value=P,w}var F=function(M){var w=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},D="";if(typeof M=="string"){var R=b(M);w.container.appendChild(R),D=p()(R),l("copy"),R.remove()}else D=p()(M),l("copy");return D},K=F;function U(P){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?U=function(w){return typeof w}:U=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},U(P)}var O=function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},w=M.action,D=w===void 0?"copy":w,R=M.container,N=M.target,Ee=M.text;if(D!=="copy"&&D!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(N!==void 0)if(N&&U(N)==="object"&&N.nodeType===1){if(D==="copy"&&N.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(D==="cut"&&(N.hasAttribute("readonly")||N.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Ee)return K(Ee,{container:R});if(N)return D==="cut"?h(N):K(N,{container:R})},je=O;function de(P){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?de=function(w){return typeof w}:de=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},de(P)}function et(P,M){if(!(P instanceof M))throw new TypeError("Cannot call a class as a function")}function tn(P,M){for(var w=0;w0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof R.action=="function"?R.action:this.defaultAction,this.target=typeof R.target=="function"?R.target:this.defaultTarget,this.text=typeof R.text=="function"?R.text:this.defaultText,this.container=de(R.container)==="object"?R.container:document.body}},{key:"listenClick",value:function(R){var N=this;this.listener=u()(R,"click",function(Ee){return N.onClick(Ee)})}},{key:"onClick",value:function(R){var N=R.delegateTarget||R.currentTarget,Ee=this.action(N)||"copy",Lt=je({action:Ee,container:this.container,target:this.target(N),text:this.text(N)});this.emit(Lt?"success":"error",{action:Ee,text:Lt,trigger:N,clearSelection:function(){N&&N.focus(),document.activeElement.blur(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(R){return vr("action",R)}},{key:"defaultTarget",value:function(R){var N=vr("target",R);if(N)return document.querySelector(N)}},{key:"defaultText",value:function(R){return vr("text",R)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(R){var N=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return K(R,N)}},{key:"cut",value:function(R){return h(R)}},{key:"isSupported",value:function(){var R=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],N=typeof R=="string"?[R]:R,Ee=!!document.queryCommandSupported;return N.forEach(function(Lt){Ee=Ee&&!!document.queryCommandSupported(Lt)}),Ee}}]),w}(s()),Zi=Xi},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,c){for(;s&&s.nodeType!==o;){if(typeof s.matches=="function"&&s.matches(c))return s;s=s.parentNode}}n.exports=a},438:function(n,o,i){var a=i(828);function s(f,p,l,d,h){var b=u.apply(this,arguments);return f.addEventListener(l,b,h),{destroy:function(){f.removeEventListener(l,b,h)}}}function c(f,p,l,d,h){return typeof f.addEventListener=="function"?s.apply(null,arguments):typeof l=="function"?s.bind(null,document).apply(null,arguments):(typeof f=="string"&&(f=document.querySelectorAll(f)),Array.prototype.map.call(f,function(b){return s(b,p,l,d,h)}))}function u(f,p,l,d){return function(h){h.delegateTarget=a(h.target,p),h.delegateTarget&&d.call(f,h)}}n.exports=c},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(n,o,i){var a=i(879),s=i(438);function c(l,d,h){if(!l&&!d&&!h)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(h))throw new TypeError("Third argument must be a Function");if(a.node(l))return u(l,d,h);if(a.nodeList(l))return f(l,d,h);if(a.string(l))return p(l,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function u(l,d,h){return l.addEventListener(d,h),{destroy:function(){l.removeEventListener(d,h)}}}function f(l,d,h){return Array.prototype.forEach.call(l,function(b){b.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(l,function(b){b.removeEventListener(d,h)})}}}function p(l,d,h){return s(document.body,l,d,h)}n.exports=c},817:function(n){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),u=document.createRange();u.selectNodeContents(i),c.removeAllRanges(),c.addRange(u),a=c.toString()}return a}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,a,s){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var c=this;function u(){c.off(i,u),a.apply(s,arguments)}return u._=a,this.on(i,u,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),c=0,u=s.length;for(c;c{"use strict";/*! - * escape-html - * Copyright(c) 2012-2013 TJ Holowaychuk - * Copyright(c) 2015 Andreas Lubbe - * Copyright(c) 2015 Tiancheng "Timothy" Gu - * MIT Licensed - */var ys=/["'&<>]/;gi.exports=xs;function xs(e){var t=""+e,r=ys.exec(t);if(!r)return t;var n,o="",i=0,a=0;for(i=r.index;i0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,a=o.isStopped,s=o.observers;return i||a?Er:(this.currentObservers=null,s.push(r),new Le(function(){n.currentObservers=null,Re(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,a=n.isStopped;o?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new k;return r.source=this,r},t.create=function(r,n){return new Vn(r,n)},t}(k);var Vn=function(e){ee(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Er},t}(E);var gt={now:function(){return(gt.delegate||Date).now()},delegate:void 0};var yt=function(e){ee(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=gt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,a=n._infiniteTimeWindow,s=n._timestampProvider,c=n._windowTime;o||(i.push(r),!a&&i.push(s.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,a=o._buffer,s=a.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=at.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){if(o===void 0&&(o=0),o!=null&&o>0||o==null&&this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);r.actions.some(function(i){return i.id===n})||(at.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Dt);var qn=function(e){ee(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Wt);var _e=new qn(zn);var z=new k(function(e){return e.complete()});function Vt(e){return e&&T(e.schedule)}function Cr(e){return e[e.length-1]}function Fe(e){return T(Cr(e))?e.pop():void 0}function ge(e){return Vt(Cr(e))?e.pop():void 0}function Nt(e,t){return typeof Cr(e)=="number"?e.pop():t}var st=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function zt(e){return T(e==null?void 0:e.then)}function qt(e){return T(e[it])}function Qt(e){return Symbol.asyncIterator&&T(e==null?void 0:e[Symbol.asyncIterator])}function Kt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function ma(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Yt=ma();function Bt(e){return T(e==null?void 0:e[Yt])}function Gt(e){return kn(this,arguments,function(){var r,n,o,i;return Ht(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,Pt(r.read())];case 3:return n=a.sent(),o=n.value,i=n.done,i?[4,Pt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,Pt(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Jt(e){return T(e==null?void 0:e.getReader)}function V(e){if(e instanceof k)return e;if(e!=null){if(qt(e))return da(e);if(st(e))return ha(e);if(zt(e))return ba(e);if(Qt(e))return Qn(e);if(Bt(e))return va(e);if(Jt(e))return ga(e)}throw Kt(e)}function da(e){return new k(function(t){var r=e[it]();if(T(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function ha(e){return new k(function(t){for(var r=0;r=2,!0))}function ie(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new E}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,c=s===void 0?!0:s;return function(u){var f=null,p=null,l=null,d=0,h=!1,b=!1,F=function(){p==null||p.unsubscribe(),p=null},K=function(){F(),f=l=null,h=b=!1},U=function(){var O=f;K(),O==null||O.unsubscribe()};return v(function(O,je){d++,!b&&!h&&F();var de=l=l!=null?l:r();je.add(function(){d--,d===0&&!b&&!h&&(p=jr(U,c))}),de.subscribe(je),f||(f=new ot({next:function(et){return de.next(et)},error:function(et){b=!0,F(),p=jr(K,o,et),de.error(et)},complete:function(){h=!0,F(),p=jr(K,a),de.complete()}}),re(O).subscribe(f))})(u)}}function jr(e,t){for(var r=[],n=2;ne.next(document)),e}function G(e,t=document){return Array.from(t.querySelectorAll(e))}function Q(e,t=document){let r=ue(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ue(e,t=document){return t.querySelector(e)||void 0}function Ve(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return C(y(document.body,"focusin"),y(document.body,"focusout")).pipe(Je(1),m(()=>{let t=Ve();return typeof t!="undefined"?e.contains(t):!1}),q(e===Ve()),B())}function Ne(e){return{x:e.offsetLeft,y:e.offsetTop}}function mo(e){return C(y(window,"load"),y(window,"resize")).pipe(He(0,_e),m(()=>Ne(e)),q(Ne(e)))}function ho(e){return{x:e.scrollLeft,y:e.scrollTop}}function rr(e){return C(y(e,"scroll"),y(window,"resize")).pipe(He(0,_e),m(()=>ho(e)),q(ho(e)))}var vo=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!Vr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Da?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!Vr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=Ua.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),go=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),xo=typeof WeakMap!="undefined"?new WeakMap:new vo,So=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=Wa.getInstance(),n=new Ja(t,r,this);xo.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){So.prototype[e]=function(){var t;return(t=xo.get(this))[e].apply(t,arguments)}});var Xa=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:So}(),wo=Xa;var Eo=new E,Za=H(()=>j(new wo(e=>{for(let t of e)Eo.next(t)}))).pipe(x(e=>C(ye,j(e)).pipe(L(()=>e.disconnect()))),X(1));function Ae(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ve(e){return Za.pipe(S(t=>t.observe(e)),x(t=>Eo.pipe(_(({target:r})=>r===e),L(()=>t.unobserve(e)),m(()=>Ae(e)))),q(Ae(e)))}function ar(e){return{width:e.scrollWidth,height:e.scrollHeight}}var Oo=new E,es=H(()=>j(new IntersectionObserver(e=>{for(let t of e)Oo.next(t)},{threshold:0}))).pipe(x(e=>C(ye,j(e)).pipe(L(()=>e.disconnect()))),X(1));function _o(e){return es.pipe(S(t=>t.observe(e)),x(t=>Oo.pipe(_(({target:r})=>r===e),L(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function To(e,t=16){return rr(e).pipe(m(({y:r})=>{let n=Ae(e),o=ar(e);return r>=o.height-n.height-t}),B())}var sr={drawer:Q("[data-md-toggle=drawer]"),search:Q("[data-md-toggle=search]")};function Mo(e){return sr[e].checked}function ze(e,t){sr[e].checked!==t&&sr[e].click()}function lt(e){let t=sr[e];return y(t,"change").pipe(m(()=>t.checked),q(t.checked))}function ts(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Lo(){return y(window,"keydown").pipe(_(e=>!(e.metaKey||e.ctrlKey)),m(e=>({mode:Mo("search")?"search":"global",type:e.key,claim(){e.preventDefault(),e.stopPropagation()}})),_(({mode:e,type:t})=>{if(e==="global"){let r=Ve();if(typeof r!="undefined")return!ts(r,t)}return!0}),ie())}function xe(){return new URL(location.href)}function cr(e){location.href=e.href}function Ao(){return new E}function Co(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Co(e,r)}function A(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="boolean"?n.setAttribute(o,t[o]):t[o]&&n.setAttribute(o,"");for(let o of r)Co(n,o);return n}function Ro(e,t){let r=t;if(e.length>r){for(;e[r]!==" "&&--r>0;);return`${e.substring(0,r)}...`}return e}function ur(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function ko(){return location.hash.substring(1)}function Ho(e){let t=A("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function rs(){return y(window,"hashchange").pipe(m(ko),q(ko()),_(e=>e.length>0),X(1))}function Po(){return rs().pipe(m(e=>ue(`[id="${e}"]`)),_(e=>typeof e!="undefined"))}function Nr(e){let t=matchMedia(e);return Zt(r=>t.addListener(()=>r(t.matches))).pipe(q(t.matches))}function Io(){let e=matchMedia("print");return C(y(window,"beforeprint").pipe(m(()=>!0)),y(window,"afterprint").pipe(m(()=>!1))).pipe(q(e.matches))}function zr(e,t){return e.pipe(x(r=>r?t():z))}function fr(e,t={credentials:"same-origin"}){return re(fetch(`${e}`,t)).pipe(_(r=>r.status===200),We(()=>z))}function Ce(e,t){return fr(e,t).pipe(x(r=>r.json()),X(1))}function $o(e,t){let r=new DOMParser;return fr(e,t).pipe(x(n=>n.text()),m(n=>r.parseFromString(n,"text/xml")),X(1))}function jo(e){let t=A("script",{src:e});return H(()=>(document.head.appendChild(t),C(y(t,"load"),y(t,"error").pipe(x(()=>Rr(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),L(()=>document.head.removeChild(t)),te(1))))}function Fo(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function Uo(){return C(y(window,"scroll",{passive:!0}),y(window,"resize",{passive:!0})).pipe(m(Fo),q(Fo()))}function Do(){return{width:innerWidth,height:innerHeight}}function Wo(){return y(window,"resize",{passive:!0}).pipe(m(Do),q(Do()))}function Vo(){return Y([Uo(),Wo()]).pipe(m(([e,t])=>({offset:e,size:t})),X(1))}function pr(e,{viewport$:t,header$:r}){let n=t.pipe(J("size")),o=Y([n,r]).pipe(m(()=>Ne(e)));return Y([r,t,o]).pipe(m(([{height:i},{offset:a,size:s},{x:c,y:u}])=>({offset:{x:a.x-c,y:a.y-u+i},size:s})))}function No(e,{tx$:t}){let r=y(e,"message").pipe(m(({data:n})=>n));return t.pipe(Ot(()=>r,{leading:!0,trailing:!0}),S(n=>e.postMessage(n)),x(()=>r),ie())}var ns=Q("#__config"),mt=JSON.parse(ns.textContent);mt.base=`${new URL(mt.base,xe())}`;function me(){return mt}function se(e){return mt.features.includes(e)}function Z(e,t){return typeof t!="undefined"?mt.translations[e].replace("#",t.toString()):mt.translations[e]}function Se(e,t=document){return Q(`[data-md-component=${e}]`,t)}function ne(e,t=document){return G(`[data-md-component=${e}]`,t)}var ei=Qe(Qr());function zo(e){return A("aside",{class:"md-annotation",tabIndex:0},A("div",{class:"md-annotation__inner md-tooltip"},A("div",{class:"md-tooltip__inner md-typeset"})),A("span",{class:"md-annotation__index"},A("span",{"data-md-annotation-id":e})))}function qo(e){return A("button",{class:"md-clipboard md-icon",title:Z("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Kr(e,t){let r=t&2,n=t&1,o=Object.keys(e.terms).filter(a=>!e.terms[a]).reduce((a,s)=>[...a,A("del",null,s)," "],[]).slice(0,-1),i=new URL(e.location);return se("search.highlight")&&i.searchParams.set("h",Object.entries(e.terms).filter(([,a])=>a).reduce((a,[s])=>`${a} ${s}`.trim(),"")),A("a",{href:`${i}`,class:"md-search-result__link",tabIndex:-1},A("article",{class:["md-search-result__article",...r?["md-search-result__article--document"]:[]].join(" "),"data-md-score":e.score.toFixed(2)},r>0&&A("div",{class:"md-search-result__icon md-icon"}),A("h1",{class:"md-search-result__title"},e.title),n>0&&e.text.length>0&&A("p",{class:"md-search-result__teaser"},Ro(e.text,320)),e.tags&&e.tags.map(a=>A("span",{class:"md-tag"},a)),n>0&&o.length>0&&A("p",{class:"md-search-result__terms"},Z("search.result.term.missing"),": ",o)))}function Qo(e){let t=e[0].score,r=[...e],n=r.findIndex(u=>!u.location.includes("#")),[o]=r.splice(n,1),i=r.findIndex(u=>u.scoreKr(u,1)),...s.length?[A("details",{class:"md-search-result__more"},A("summary",{tabIndex:-1},s.length>0&&s.length===1?Z("search.result.more.one"):Z("search.result.more.other",s.length)),s.map(u=>Kr(u,1)))]:[]];return A("li",{class:"md-search-result__item"},c)}function Ko(e){return A("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>A("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?ur(r):r)))}function Yo(e){return A("div",{class:"md-typeset__scrollwrap"},A("div",{class:"md-typeset__table"},e))}function os(e){let t=me(),r=new URL(`../${e.version}/`,t.base);return A("li",{class:"md-version__item"},A("a",{href:r.toString(),class:"md-version__link"},e.title))}function Bo(e,t){return A("div",{class:"md-version"},A("button",{class:"md-version__current","aria-label":Z("select.version.title")},t.title),A("ul",{class:"md-version__list"},e.map(os)))}function is(e,t){let r=H(()=>Y([mo(e),rr(t)])).pipe(m(([{x:n,y:o},i])=>{let{width:a}=Ae(e);return{x:n-i.x+a/2,y:o-i.y}}));return tr(e).pipe(x(n=>r.pipe(m(o=>({active:n,offset:o})),te(+!n||1/0))))}function Go(e,t){return H(()=>{let r=new E;r.subscribe({next({offset:i}){e.style.setProperty("--md-tooltip-x",`${i.x}px`),e.style.setProperty("--md-tooltip-y",`${i.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),r.pipe(Dr(500,_e),m(()=>t.getBoundingClientRect()),m(({x:i})=>i)).subscribe({next(i){i?e.style.setProperty("--md-tooltip-0",`${-i}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}});let n=Q(":scope > :last-child",e),o=y(n,"mousedown",{once:!0});return r.pipe(x(({active:i})=>i?o:z),S(i=>i.preventDefault())).subscribe(()=>e.blur()),is(e,t).pipe(S(i=>r.next(i)),L(()=>r.complete()),m(i=>I({ref:e},i)))})}function as(e){let t=[];for(let r of G(".c, .c1, .cm",e)){let n,o=r.firstChild;if(o instanceof Text)for(;n=/\((\d+)\)/.exec(o.textContent);){let i=o.splitText(n.index);o=i.splitText(n[0].length),t.push(i)}}return t}function Jo(e,t){t.append(...Array.from(e.childNodes))}function Xo(e,t,{print$:r}){let n=new Map;for(let o of as(t)){let[,i]=o.textContent.match(/\((\d+)\)/);ue(`li:nth-child(${i})`,e)&&(n.set(+i,zo(+i)),o.replaceWith(n.get(+i)))}return n.size===0?z:H(()=>{let o=new E;return r.pipe(ae(o.pipe(pe(1)))).subscribe(i=>{e.hidden=!i;for(let[a,s]of n){let c=Q(".md-typeset",s),u=Q(`li:nth-child(${a})`,e);i?Jo(c,u):Jo(u,c)}}),C(...[...n].map(([,i])=>Go(i,t))).pipe(L(()=>o.complete()),ie())})}var ss=0;function ti(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return ti(t)}}function Zo(e){return ve(e).pipe(m(({width:t})=>({scrollable:ar(e).width>t})),J("scrollable"))}function ri(e,t){let{matches:r}=matchMedia("(hover)"),n=H(()=>{let o=new E;if(o.subscribe(({scrollable:a})=>{a&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")}),ei.default.isSupported()){let a=e.closest("pre");a.id=`__code_${++ss}`,a.insertBefore(qo(a.id),e)}let i=e.closest([":not(td):not(.code) > .highlight",".highlighttable"].join(", "));if(i instanceof HTMLElement){let a=ti(i);if(typeof a!="undefined"&&(i.classList.contains("annotate")||se("content.code.annotate"))){let s=Xo(a,e,t);return Zo(e).pipe(S(c=>o.next(c)),L(()=>o.complete()),m(c=>I({ref:e},c)),Xe(ve(i).pipe(ae(o.pipe(pe(1))),m(({width:c,height:u})=>c&&u),B(),x(c=>c?s:z))))}}return Zo(e).pipe(S(a=>o.next(a)),L(()=>o.complete()),m(a=>I({ref:e},a)))});return _o(e).pipe(_(o=>o),te(1),x(()=>n))}var ni=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:transparent}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color)}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}defs #flowchart-circleEnd,defs #flowchart-circleStart,defs #flowchart-crossEnd,defs #flowchart-crossStart,defs #flowchart-pointEnd,defs #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}.actor,defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{stroke:var(--md-mermaid-node-fg-color)}text.actor>tspan{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-default-fg-color--lighter)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-edge-color)}.loopText>tspan,.messageText{font-family:var(--md-mermaid-font-family)!important}#arrowhead path,.loopText>tspan,.messageText{fill:var(--md-mermaid-edge-color);stroke:none}.loopLine{stroke:var(--md-mermaid-node-fg-color)}.labelBox,.loopLine{fill:var(--md-mermaid-node-bg-color)}.labelBox{stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-node-fg-color);font-family:var(--md-mermaid-font-family)}";var Yr,us=0;function fs(){return typeof mermaid=="undefined"||mermaid instanceof Element?jo("https://unpkg.com/mermaid@9.0.1/dist/mermaid.min.js"):j(void 0)}function oi(e){return e.classList.remove("mermaid"),Yr||(Yr=fs().pipe(S(()=>mermaid.initialize({startOnLoad:!1,themeCSS:ni})),m(()=>{}),X(1))),Yr.subscribe(()=>{e.classList.add("mermaid");let t=`__mermaid_${us++}`,r=A("div",{class:"mermaid"});mermaid.mermaidAPI.render(t,e.textContent,n=>{let o=r.attachShadow({mode:"closed"});o.innerHTML=n,e.replaceWith(r)})}),Yr.pipe(m(()=>({ref:e})))}function ps(e,{target$:t,print$:r}){let n=!0;return C(t.pipe(m(o=>o.closest("details:not([open])")),_(o=>e===o),m(()=>({action:"open",reveal:!0}))),r.pipe(_(o=>o||!n),S(()=>n=e.open),m(o=>({action:o?"open":"close"}))))}function ii(e,t){return H(()=>{let r=new E;return r.subscribe(({action:n,reveal:o})=>{n==="open"?e.setAttribute("open",""):e.removeAttribute("open"),o&&e.scrollIntoView()}),ps(e,t).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))})}var ai=A("table");function si(e){return e.replaceWith(ai),ai.replaceWith(Yo(e)),j({ref:e})}function ls(e){let t=G(":scope > input",e),r=t.find(n=>n.checked)||t[0];return C(...t.map(n=>y(n,"change").pipe(m(()=>({active:Q(`label[for=${n.id}]`)}))))).pipe(q({active:Q(`label[for=${r.id}]`)}))}function ci(e){let t=Q(".tabbed-labels",e);return H(()=>{let r=new E;return Y([r,ve(e)]).pipe(He(1,_e),ae(r.pipe(pe(1)))).subscribe({next([{active:n}]){let o=Ne(n),{width:i}=Ae(n);e.style.setProperty("--md-indicator-x",`${o.x}px`),e.style.setProperty("--md-indicator-width",`${i}px`),t.scrollTo({behavior:"smooth",left:o.x})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),ls(e).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))}).pipe(Ye(ce))}function ui(e,{target$:t,print$:r}){return C(...G("pre:not(.mermaid) > code",e).map(n=>ri(n,{print$:r})),...G("pre.mermaid",e).map(n=>oi(n)),...G("table:not([class])",e).map(n=>si(n)),...G("details",e).map(n=>ii(n,{target$:t,print$:r})),...G("[data-tabs]",e).map(n=>ci(n)))}function ms(e,{alert$:t}){return t.pipe(x(r=>C(j(!0),j(!1).pipe(Ie(2e3))).pipe(m(n=>({message:r,active:n})))))}function fi(e,t){let r=Q(".md-typeset",e);return H(()=>{let n=new E;return n.subscribe(({message:o,active:i})=>{r.textContent=o,i?e.setAttribute("data-md-state","open"):e.removeAttribute("data-md-state")}),ms(e,t).pipe(S(o=>n.next(o)),L(()=>n.complete()),m(o=>I({ref:e},o)))})}function ds({viewport$:e}){if(!se("header.autohide"))return j(!1);let t=e.pipe(m(({offset:{y:o}})=>o),Te(2,1),m(([o,i])=>[oMath.abs(i-o.y)>100),m(([,[o]])=>o),B()),n=lt("search");return Y([e,n]).pipe(m(([{offset:o},i])=>o.y>400&&!i),B(),x(o=>o?r:j(!1)),q(!1))}function pi(e,t){return H(()=>Y([ve(e),ds(t)])).pipe(m(([{height:r},n])=>({height:r,hidden:n})),B((r,n)=>r.height===n.height&&r.hidden===n.hidden),X(1))}function li(e,{header$:t,main$:r}){return H(()=>{let n=new E;return n.pipe(J("active"),Ge(t)).subscribe(([{active:o},{hidden:i}])=>{o?e.setAttribute("data-md-state",i?"hidden":"shadow"):e.removeAttribute("data-md-state")}),r.subscribe(n),t.pipe(ae(n.pipe(pe(1))),m(o=>I({ref:e},o)))})}function hs(e,{viewport$:t,header$:r}){return pr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:n}})=>{let{height:o}=Ae(e);return{active:n>=o}}),J("active"))}function mi(e,t){return H(()=>{let r=new E;r.subscribe(({active:o})=>{o?e.setAttribute("data-md-state","active"):e.removeAttribute("data-md-state")});let n=ue("article h1");return typeof n=="undefined"?z:hs(n,t).pipe(S(o=>r.next(o)),L(()=>r.complete()),m(o=>I({ref:e},o)))})}function di(e,{viewport$:t,header$:r}){let n=r.pipe(m(({height:i})=>i),B()),o=n.pipe(x(()=>ve(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),J("bottom"))));return Y([n,o,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:c},size:{height:u}}])=>(u=Math.max(0,u-Math.max(0,a-c,i)-Math.max(0,u+c-s)),{offset:a-i,height:u,active:a-i<=c})),B((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function bs(e){let t=__md_get("__palette")||{index:e.findIndex(r=>matchMedia(r.getAttribute("data-md-color-media")).matches)};return j(...e).pipe(oe(r=>y(r,"change").pipe(m(()=>r))),q(e[Math.max(0,t.index)]),m(r=>({index:e.indexOf(r),color:{scheme:r.getAttribute("data-md-color-scheme"),primary:r.getAttribute("data-md-color-primary"),accent:r.getAttribute("data-md-color-accent")}})),X(1))}function hi(e){return H(()=>{let t=new E;t.subscribe(n=>{document.body.setAttribute("data-md-color-switching","");for(let[o,i]of Object.entries(n.color))document.body.setAttribute(`data-md-color-${o}`,i);for(let o=0;o{document.body.removeAttribute("data-md-color-switching")});let r=G("input",e);return bs(r).pipe(S(n=>t.next(n)),L(()=>t.complete()),m(n=>I({ref:e},n)))})}var Br=Qe(Qr());function vs(e){e.setAttribute("data-md-copying","");let t=e.innerText;return e.removeAttribute("data-md-copying"),t}function bi({alert$:e}){Br.default.isSupported()&&new k(t=>{new Br.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||vs(Q(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(S(t=>{t.trigger.focus()}),m(()=>Z("clipboard.copied"))).subscribe(e)}function gs(e){if(e.length<2)return[""];let[t,r]=[...e].sort((o,i)=>o.length-i.length).map(o=>o.replace(/[^/]+$/,"")),n=0;if(t===r)n=t.length;else for(;t.charCodeAt(n)===r.charCodeAt(n);)n++;return e.map(o=>o.replace(t.slice(0,n),""))}function lr(e){let t=__md_get("__sitemap",sessionStorage,e);if(t)return j(t);{let r=me();return $o(new URL("sitemap.xml",e||r.base)).pipe(m(n=>gs(G("loc",n).map(o=>o.textContent))),Pe([]),S(n=>__md_set("__sitemap",n,sessionStorage,e)))}}function vi({document$:e,location$:t,viewport$:r}){let n=me();if(location.protocol==="file:")return;"scrollRestoration"in history&&(history.scrollRestoration="manual",y(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}));let o=ue("link[rel=icon]");typeof o!="undefined"&&(o.href=o.href);let i=lr().pipe(m(u=>u.map(f=>`${new URL(f,n.base)}`)),x(u=>y(document.body,"click").pipe(_(f=>!f.metaKey&&!f.ctrlKey),x(f=>{if(f.target instanceof Element){let p=f.target.closest("a");if(p&&!p.target){let l=new URL(p.href);if(l.search="",l.hash="",l.pathname!==location.pathname&&u.includes(l.toString()))return f.preventDefault(),j({url:new URL(p.href)})}}return ye}))),ie()),a=y(window,"popstate").pipe(_(u=>u.state!==null),m(u=>({url:new URL(location.href),offset:u.state})),ie());C(i,a).pipe(B((u,f)=>u.url.href===f.url.href),m(({url:u})=>u)).subscribe(t);let s=t.pipe(J("pathname"),x(u=>fr(u.href).pipe(We(()=>(cr(u),ye)))),ie());i.pipe(ft(s)).subscribe(({url:u})=>{history.pushState({},"",`${u}`)});let c=new DOMParser;s.pipe(x(u=>u.text()),m(u=>c.parseFromString(u,"text/html"))).subscribe(e),e.pipe($e(1)).subscribe(u=>{for(let f of["title","link[rel=canonical]","meta[name=author]","meta[name=description]","[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...se("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let p=ue(f),l=ue(f,u);typeof p!="undefined"&&typeof l!="undefined"&&p.replaceWith(l)}}),e.pipe($e(1),m(()=>Se("container")),x(u=>G("script",u)),Pr(u=>{let f=A("script");if(u.src){for(let p of u.getAttributeNames())f.setAttribute(p,u.getAttribute(p));return u.replaceWith(f),new k(p=>{f.onload=()=>p.complete()})}else return f.textContent=u.textContent,u.replaceWith(f),z})).subscribe(),C(i,a).pipe(ft(e)).subscribe(({url:u,offset:f})=>{u.hash&&!f?Ho(u.hash):window.scrollTo(0,(f==null?void 0:f.y)||0)}),r.pipe(Et(i),Je(250),J("offset")).subscribe(({offset:u})=>{history.replaceState(u,"")}),C(i,a).pipe(Te(2,1),_(([u,f])=>u.url.pathname===f.url.pathname),m(([,u])=>u)).subscribe(({offset:u})=>{window.scrollTo(0,(u==null?void 0:u.y)||0)})}var Ss=Qe(Gr());var yi=Qe(Gr());function Jr(e,t){let r=new RegExp(e.separator,"img"),n=(o,i,a)=>`${i}${a}`;return o=>{o=o.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator})(${o.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(t?(0,yi.default)(a):a).replace(i,n).replace(/<\/mark>(\s+)]*>/img,"$1")}}function xi(e){return e.split(/"([^"]+)"/g).map((t,r)=>r&1?t.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):t).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").trim()}function dt(e){return e.type===1}function Si(e){return e.type===2}function ht(e){return e.type===3}function Es({config:e,docs:t}){e.lang.length===1&&e.lang[0]==="en"&&(e.lang=[Z("search.config.lang")]),e.separator==="[\\s\\-]+"&&(e.separator=Z("search.config.separator"));let n={pipeline:Z("search.config.pipeline").split(/\s*,\s*/).filter(Boolean),suggestions:se("search.suggest")};return{config:e,docs:t,options:n}}function wi(e,t){let r=me(),n=new Worker(e),o=new E,i=No(n,{tx$:o}).pipe(m(a=>{if(ht(a))for(let s of a.data.items)for(let c of s)c.location=`${new URL(c.location,r.base)}`;return a}),ie());return re(t).pipe(m(a=>({type:0,data:Es(a)}))).subscribe(o.next.bind(o)),{tx$:o,rx$:i}}function Ei({document$:e}){let t=me(),r=Ce(new URL("../versions.json",t.base)),n=r.pipe(m(o=>{let[,i]=t.base.match(/([^/]+)\/?$/);return o.find(({version:a,aliases:s})=>a===i||s.includes(i))||o[0]}));Y([r,n]).pipe(m(([o,i])=>new Map(o.filter(a=>a!==i).map(a=>[`${new URL(`../${a.version}/`,t.base)}`,a]))),x(o=>y(document.body,"click").pipe(_(i=>!i.metaKey&&!i.ctrlKey),x(i=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&o.has(a.href))return i.preventDefault(),j(a.href)}return z}),x(i=>{let{version:a}=o.get(i);return lr(new URL(i)).pipe(m(s=>{let u=xe().href.replace(t.base,"");return s.includes(u)?new URL(`../${a}/${u}`,t.base):new URL(i)}))})))).subscribe(o=>cr(o)),Y([r,n]).subscribe(([o,i])=>{Q(".md-header__topic").appendChild(Bo(o,i))}),e.pipe(x(()=>n)).subscribe(o=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){let s=((a=t.version)==null?void 0:a.default)||"latest";i=!o.aliases.includes(s),__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ne("outdated"))s.hidden=!1})}function Os(e,{rx$:t}){let r=(__search==null?void 0:__search.transform)||xi,{searchParams:n}=xe();n.has("q")&&ze("search",!0);let o=t.pipe(_(dt),te(1),m(()=>n.get("q")||""));lt("search").pipe(_(s=>!s),te(1)).subscribe(()=>{let s=new URL(location.href);s.searchParams.delete("q"),history.replaceState({},"",`${s}`)}),o.subscribe(s=>{s&&(e.value=s,e.focus())});let i=tr(e),a=C(y(e,"keyup"),y(e,"focus").pipe(Ie(1)),o).pipe(m(()=>r(e.value)),q(""),B());return Y([a,i]).pipe(m(([s,c])=>({value:s,focus:c})),X(1))}function Oi(e,{tx$:t,rx$:r}){let n=new E;return n.pipe(J("value"),m(({value:o})=>({type:2,data:o}))).subscribe(t.next.bind(t)),n.pipe(J("focus")).subscribe(({focus:o})=>{o?(ze("search",o),e.placeholder=""):e.placeholder=Z("search.placeholder")}),y(e.form,"reset").pipe(ae(n.pipe(pe(1)))).subscribe(()=>e.focus()),Os(e,{tx$:t,rx$:r}).pipe(S(o=>n.next(o)),L(()=>n.complete()),m(o=>I({ref:e},o)))}function _i(e,{rx$:t},{query$:r}){let n=new E,o=To(e.parentElement).pipe(_(Boolean)),i=Q(":scope > :first-child",e),a=Q(":scope > :last-child",e),s=t.pipe(_(dt),te(1));return n.pipe(Me(r),Et(s)).subscribe(([{items:u},{value:f}])=>{if(f)switch(u.length){case 0:i.textContent=Z("search.result.none");break;case 1:i.textContent=Z("search.result.one");break;default:i.textContent=Z("search.result.other",ur(u.length))}else i.textContent=Z("search.result.placeholder")}),n.pipe(S(()=>a.innerHTML=""),x(({items:u})=>C(j(...u.slice(0,10)),j(...u.slice(10)).pipe(Te(4),Wr(o),x(([f])=>f))))).subscribe(u=>a.appendChild(Qo(u))),t.pipe(_(ht),m(({data:u})=>u)).pipe(S(u=>n.next(u)),L(()=>n.complete()),m(u=>I({ref:e},u)))}function _s(e,{query$:t}){return t.pipe(m(({value:r})=>{let n=xe();return n.hash="",n.searchParams.delete("h"),n.searchParams.set("q",r),{url:n}}))}function Ti(e,t){let r=new E;return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),y(e,"click").subscribe(n=>n.preventDefault()),_s(e,t).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))}function Mi(e,{rx$:t},{keyboard$:r}){let n=new E,o=Se("search-query"),i=C(y(o,"keydown"),y(o,"focus")).pipe(ke(ce),m(()=>o.value),B());return n.pipe(Ge(i),m(([{suggestions:s},c])=>{let u=c.split(/([\s-]+)/);if((s==null?void 0:s.length)&&u[u.length-1]){let f=s[s.length-1];f.startsWith(u[u.length-1])&&(u[u.length-1]=f)}else u.length=0;return u})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(_(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&o.selectionStart===o.value.length&&(o.value=e.innerText);break}}),t.pipe(_(ht),m(({data:s})=>s)).pipe(S(s=>n.next(s)),L(()=>n.complete()),m(()=>({ref:e})))}function Li(e,{index$:t,keyboard$:r}){let n=me();try{let o=(__search==null?void 0:__search.worker)||n.search,i=wi(o,t),a=Se("search-query",e),s=Se("search-result",e),{tx$:c,rx$:u}=i;c.pipe(_(Si),ft(u.pipe(_(dt))),te(1)).subscribe(c.next.bind(c)),r.pipe(_(({mode:l})=>l==="search")).subscribe(l=>{let d=Ve();switch(l.type){case"Enter":if(d===a){let h=new Map;for(let b of G(":first-child [href]",s)){let F=b.firstElementChild;h.set(b,parseFloat(F.getAttribute("data-md-score")))}if(h.size){let[[b]]=[...h].sort(([,F],[,K])=>K-F);b.click()}l.claim()}break;case"Escape":case"Tab":ze("search",!1),a.blur();break;case"ArrowUp":case"ArrowDown":if(typeof d=="undefined")a.focus();else{let h=[a,...G(":not(details) > [href], summary, details[open] [href]",s)],b=Math.max(0,(Math.max(0,h.indexOf(d))+h.length+(l.type==="ArrowUp"?-1:1))%h.length);h[b].focus()}l.claim();break;default:a!==Ve()&&a.focus()}}),r.pipe(_(({mode:l})=>l==="global")).subscribe(l=>{switch(l.type){case"f":case"s":case"/":a.focus(),a.select(),l.claim();break}});let f=Oi(a,i),p=_i(s,i,{query$:f});return C(f,p).pipe(Xe(...ne("search-share",e).map(l=>Ti(l,{query$:f})),...ne("search-suggest",e).map(l=>Mi(l,i,{keyboard$:r}))))}catch(o){return e.hidden=!0,ye}}function Ai(e,{index$:t,location$:r}){return Y([t,r.pipe(q(xe()),_(n=>!!n.searchParams.get("h")))]).pipe(m(([n,o])=>Jr(n.config,!0)(o.searchParams.get("h"))),m(n=>{var a;let o=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let c=s.textContent,u=n(c);u.length>c.length&&o.set(s,u)}for(let[s,c]of o){let{childNodes:u}=A("span",null,c);s.replaceWith(...Array.from(u))}return{ref:e,nodes:o}}))}function Ts(e,{viewport$:t,main$:r}){let n=e.parentElement,o=n.offsetTop-n.parentElement.offsetTop;return Y([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(o,Math.max(0,s-i))-o,{height:a,locked:s>=i+o})),B((i,a)=>i.height===a.height&&i.locked===a.locked))}function Xr(e,n){var o=n,{header$:t}=o,r=on(o,["header$"]);let i=Q(".md-sidebar__scrollwrap",e),{y:a}=Ne(i);return H(()=>{let s=new E;return s.pipe(He(0,_e),Me(t)).subscribe({next([{height:c},{height:u}]){i.style.height=`${c-2*a}px`,e.style.top=`${u}px`},complete(){i.style.height="",e.style.top=""}}),Ts(e,r).pipe(S(c=>s.next(c)),L(()=>s.complete()),m(c=>I({ref:e},c)))})}function Ci(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return St(Ce(`${r}/releases/latest`).pipe(m(n=>({version:n.tag_name})),Pe({})),Ce(r).pipe(m(n=>({stars:n.stargazers_count,forks:n.forks_count})),Pe({}))).pipe(m(([n,o])=>I(I({},n),o)))}else{let r=`https://api.github.com/users/${e}`;return Ce(r).pipe(m(n=>({repositories:n.public_repos})),Pe({}))}}function Ri(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ce(r).pipe(m(({star_count:n,forks_count:o})=>({stars:n,forks:o})),Pe({}))}function ki(e){let[t]=e.match(/(git(?:hub|lab))/i)||[];switch(t.toLowerCase()){case"github":let[,r,n]=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);return Ci(r,n);case"gitlab":let[,o,i]=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i);return Ri(o,i);default:return z}}var Ms;function Ls(e){return Ms||(Ms=H(()=>{let t=__md_get("__source",sessionStorage);return t?j(t):ki(e.href).pipe(S(r=>__md_set("__source",r,sessionStorage)))}).pipe(We(()=>z),_(t=>Object.keys(t).length>0),m(t=>({facts:t})),X(1)))}function Hi(e){let t=Q(":scope > :last-child",e);return H(()=>{let r=new E;return r.subscribe(({facts:n})=>{t.appendChild(Ko(n)),t.setAttribute("data-md-state","done")}),Ls(e).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))})}function As(e,{viewport$:t,header$:r}){return ve(document.body).pipe(x(()=>pr(e,{header$:r,viewport$:t})),m(({offset:{y:n}})=>({hidden:n>=10})),J("hidden"))}function Pi(e,t){return H(()=>{let r=new E;return r.subscribe({next({hidden:n}){n?e.setAttribute("data-md-state","hidden"):e.removeAttribute("data-md-state")},complete(){e.removeAttribute("data-md-state")}}),(se("navigation.tabs.sticky")?j({hidden:!1}):As(e,t)).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>I({ref:e},n)))})}function Cs(e,{viewport$:t,header$:r}){let n=new Map,o=G("[href^=\\#]",e);for(let s of o){let c=decodeURIComponent(s.hash.substring(1)),u=ue(`[id="${c}"]`);typeof u!="undefined"&&n.set(s,u)}let i=r.pipe(J("height"),m(({height:s})=>{let c=Se("main"),u=Q(":scope > :first-child",c);return s+.8*(u.offsetTop-c.offsetTop)}),ie());return ve(document.body).pipe(J("height"),x(s=>H(()=>{let c=[];return j([...n].reduce((u,[f,p])=>{for(;c.length&&n.get(c[c.length-1]).tagName>=p.tagName;)c.pop();let l=p.offsetTop;for(;!l&&p.parentElement;)p=p.parentElement,l=p.offsetTop;return u.set([...c=[...c,f]].reverse(),l)},new Map))}).pipe(m(c=>new Map([...c].sort(([,u],[,f])=>u-f))),Ge(i),x(([c,u])=>t.pipe($r(([f,p],{offset:{y:l},size:d})=>{let h=l+d.height>=Math.floor(s.height);for(;p.length;){let[,b]=p[0];if(b-u=l&&!h)p=[f.pop(),...p];else break}return[f,p]},[[],[...c]]),B((f,p)=>f[0]===p[0]&&f[1]===p[1])))))).pipe(m(([s,c])=>({prev:s.map(([u])=>u),next:c.map(([u])=>u)})),q({prev:[],next:[]}),Te(2,1),m(([s,c])=>s.prev.length{let o=new E;return o.subscribe(({prev:i,next:a})=>{for(let[s]of a)s.removeAttribute("data-md-state"),s.classList.remove("md-nav__link--active");for(let[s,[c]]of i.entries())c.setAttribute("data-md-state","blur"),c.classList.toggle("md-nav__link--active",s===i.length-1)}),se("navigation.tracking")&&t.pipe(ae(o.pipe(pe(1))),J("offset"),Je(250),$e(1),ae(n.pipe($e(1))),wt({delay:250}),Me(o)).subscribe(([,{prev:i}])=>{let a=xe(),s=i[i.length-1];if(s&&s.length){let[c]=s,{hash:u}=new URL(c.href);a.hash!==u&&(a.hash=u,history.replaceState({},"",`${a}`))}else a.hash="",history.replaceState({},"",`${a}`)}),Cs(e,{viewport$:t,header$:r}).pipe(S(i=>o.next(i)),L(()=>o.complete()),m(i=>I({ref:e},i)))})}function Rs(e,{viewport$:t,main$:r,target$:n}){let o=t.pipe(m(({offset:{y:a}})=>a),Te(2,1),m(([a,s])=>a>s&&s>0),B()),i=r.pipe(m(({active:a})=>a));return Y([i,o]).pipe(m(([a,s])=>!(a&&s)),B(),ae(n.pipe($e(1))),er(!0),wt({delay:250}),m(a=>({hidden:a})))}function $i(e,{viewport$:t,header$:r,main$:n,target$:o}){let i=new E;return i.subscribe({next({hidden:a}){a?(e.setAttribute("data-md-state","hidden"),e.setAttribute("tabindex","-1"),e.blur()):(e.removeAttribute("data-md-state"),e.removeAttribute("tabindex"))},complete(){e.style.top="",e.setAttribute("data-md-state","hidden"),e.removeAttribute("tabindex")}}),r.pipe(ae(i.pipe(er(0),pe(1))),J("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),Rs(e,{viewport$:t,main$:n,target$:o}).pipe(S(a=>i.next(a)),L(()=>i.complete()),m(a=>I({ref:e},a)))}function ji({document$:e,tablet$:t}){e.pipe(x(()=>G("[data-md-state=indeterminate]")),S(r=>{r.indeterminate=!0,r.checked=!1}),oe(r=>y(r,"change").pipe(Fr(()=>r.hasAttribute("data-md-state")),m(()=>r))),Me(t)).subscribe(([r,n])=>{r.removeAttribute("data-md-state"),n&&(r.checked=!1)})}function ks(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Fi({document$:e}){e.pipe(x(()=>G("[data-md-scrollfix]")),S(t=>t.removeAttribute("data-md-scrollfix")),_(ks),oe(t=>y(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Ui({viewport$:e,tablet$:t}){Y([lt("search"),t]).pipe(m(([r,n])=>r&&!n),x(r=>j(r).pipe(Ie(r?400:100))),Me(e)).subscribe(([r,{offset:{y:n}}])=>{if(r)document.body.setAttribute("data-md-state","lock"),document.body.style.top=`-${n}px`;else{let o=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-state"),document.body.style.top="",o&&window.scrollTo(0,o)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let n=e[r];typeof n!="object"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?t.insertBefore(this.previousSibling,n):t.replaceChild(n,this)}}}));document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var Ze=lo(),dr=Ao(),Tt=Po(),Zr=Lo(),we=Vo(),hr=Nr("(min-width: 960px)"),Wi=Nr("(min-width: 1220px)"),Vi=Io(),Ni=me(),zi=document.forms.namedItem("search")?(__search==null?void 0:__search.index)||Ce(new URL("search/search_index.json",Ni.base)):ye,en=new E;bi({alert$:en});se("navigation.instant")&&vi({document$:Ze,location$:dr,viewport$:we});var Di;((Di=Ni.version)==null?void 0:Di.provider)==="mike"&&Ei({document$:Ze});C(dr,Tt).pipe(Ie(125)).subscribe(()=>{ze("drawer",!1),ze("search",!1)});Zr.pipe(_(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=ue("[href][rel=prev]");typeof t!="undefined"&&t.click();break;case"n":case".":let r=ue("[href][rel=next]");typeof r!="undefined"&&r.click();break}});ji({document$:Ze,tablet$:hr});Fi({document$:Ze});Ui({viewport$:we,tablet$:hr});var qe=pi(Se("header"),{viewport$:we}),mr=Ze.pipe(m(()=>Se("main")),x(e=>di(e,{viewport$:we,header$:qe})),X(1)),Hs=C(...ne("dialog").map(e=>fi(e,{alert$:en})),...ne("header").map(e=>li(e,{viewport$:we,header$:qe,main$:mr})),...ne("palette").map(e=>hi(e)),...ne("search").map(e=>Li(e,{index$:zi,keyboard$:Zr})),...ne("source").map(e=>Hi(e))),Ps=H(()=>C(...ne("content").map(e=>ui(e,{target$:Tt,print$:Vi})),...ne("content").map(e=>se("search.highlight")?Ai(e,{index$:zi,location$:dr}):z),...ne("header-title").map(e=>mi(e,{viewport$:we,header$:qe})),...ne("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?zr(Wi,()=>Xr(e,{viewport$:we,header$:qe,main$:mr})):zr(hr,()=>Xr(e,{viewport$:we,header$:qe,main$:mr}))),...ne("tabs").map(e=>Pi(e,{viewport$:we,header$:qe})),...ne("toc").map(e=>Ii(e,{viewport$:we,header$:qe,target$:Tt})),...ne("top").map(e=>$i(e,{viewport$:we,header$:qe,main$:mr,target$:Tt})))),qi=Ze.pipe(x(()=>Ps),Xe(Hs),X(1));qi.subscribe();window.document$=Ze;window.location$=dr;window.target$=Tt;window.keyboard$=Zr;window.viewport$=we;window.tablet$=hr;window.screen$=Wi;window.print$=Vi;window.alert$=en;window.component$=qi;})(); -//# sourceMappingURL=bundle.748e2769.min.js.map - diff --git a/assets/javascripts/bundle.c2e1ee47.min.js b/assets/javascripts/bundle.c2e1ee47.min.js new file mode 100644 index 000000000..fa942889b --- /dev/null +++ b/assets/javascripts/bundle.c2e1ee47.min.js @@ -0,0 +1,29 @@ +(()=>{var ea=Object.create;var yr=Object.defineProperty;var ta=Object.getOwnPropertyDescriptor;var ra=Object.getOwnPropertyNames,Ct=Object.getOwnPropertySymbols,na=Object.getPrototypeOf,xr=Object.prototype.hasOwnProperty,nn=Object.prototype.propertyIsEnumerable;var rn=(e,t,r)=>t in e?yr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,j=(e,t)=>{for(var r in t||(t={}))xr.call(t,r)&&rn(e,r,t[r]);if(Ct)for(var r of Ct(t))nn.call(t,r)&&rn(e,r,t[r]);return e};var on=(e,t)=>{var r={};for(var n in e)xr.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&Ct)for(var n of Ct(e))t.indexOf(n)<0&&nn.call(e,n)&&(r[n]=e[n]);return r};var bt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var oa=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ra(t))!xr.call(e,o)&&o!==r&&yr(e,o,{get:()=>t[o],enumerable:!(n=ta(t,o))||n.enumerable});return e};var Qe=(e,t,r)=>(r=e!=null?ea(na(e)):{},oa(t||!e||!e.__esModule?yr(r,"default",{value:e,enumerable:!0}):r,e));var sn=bt((Sr,an)=>{(function(e,t){typeof Sr=="object"&&typeof an!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Sr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(O){return!!(O&&O!==document&&O.nodeName!=="HTML"&&O.nodeName!=="BODY"&&"classList"in O&&"contains"in O.classList)}function c(O){var Fe=O.type,he=O.tagName;return!!(he==="INPUT"&&a[Fe]&&!O.readOnly||he==="TEXTAREA"&&!O.readOnly||O.isContentEditable)}function u(O){O.classList.contains("focus-visible")||(O.classList.add("focus-visible"),O.setAttribute("data-focus-visible-added",""))}function f(O){!O.hasAttribute("data-focus-visible-added")||(O.classList.remove("focus-visible"),O.removeAttribute("data-focus-visible-added"))}function p(O){O.metaKey||O.altKey||O.ctrlKey||(s(r.activeElement)&&u(r.activeElement),n=!0)}function l(O){n=!1}function d(O){!s(O.target)||(n||c(O.target))&&u(O.target)}function h(O){!s(O.target)||(O.target.classList.contains("focus-visible")||O.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),f(O.target))}function b(O){document.visibilityState==="hidden"&&(o&&(n=!0),U())}function U(){document.addEventListener("mousemove",D),document.addEventListener("mousedown",D),document.addEventListener("mouseup",D),document.addEventListener("pointermove",D),document.addEventListener("pointerdown",D),document.addEventListener("pointerup",D),document.addEventListener("touchmove",D),document.addEventListener("touchstart",D),document.addEventListener("touchend",D)}function Y(){document.removeEventListener("mousemove",D),document.removeEventListener("mousedown",D),document.removeEventListener("mouseup",D),document.removeEventListener("pointermove",D),document.removeEventListener("pointerdown",D),document.removeEventListener("pointerup",D),document.removeEventListener("touchmove",D),document.removeEventListener("touchstart",D),document.removeEventListener("touchend",D)}function D(O){O.target.nodeName&&O.target.nodeName.toLowerCase()==="html"||(n=!1,Y())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",l,!0),document.addEventListener("pointerdown",l,!0),document.addEventListener("touchstart",l,!0),document.addEventListener("visibilitychange",b,!0),U(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var cn=bt(wr=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(u){return!1}},r=t(),n=function(u){var f={next:function(){var p=u.shift();return{done:p===void 0,value:p}}};return r&&(f[Symbol.iterator]=function(){return f}),f},o=function(u){return encodeURIComponent(u).replace(/%20/g,"+")},i=function(u){return decodeURIComponent(String(u).replace(/\+/g," "))},a=function(){var u=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var l=typeof p;if(l!=="undefined")if(l==="string")p!==""&&this._fromString(p);else if(p instanceof u){var d=this;p.forEach(function(Y,D){d.append(D,Y)})}else if(p!==null&&l==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),u._entries&&(u._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:wr);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(c,u){typeof c!="string"&&(c=String(c)),u&&typeof u!="string"&&(u=String(u));var f=document,p;if(u&&(e.location===void 0||u!==e.location.href)){u=u.toLowerCase(),f=document.implementation.createHTMLDocument(""),p=f.createElement("base"),p.href=u,f.head.appendChild(p);try{if(p.href.indexOf(u)!==0)throw new Error(p.href)}catch(O){throw new Error("URL unable to set base "+u+" due to "+O)}}var l=f.createElement("a");l.href=c,p&&(f.body.appendChild(l),l.href=l.href);var d=f.createElement("input");if(d.type="url",d.value=c,l.protocol===":"||!/:/.test(l.href)||!d.checkValidity()&&!u)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:l});var h=new e.URLSearchParams(this.search),b=!0,U=!0,Y=this;["append","delete","set"].forEach(function(O){var Fe=h[O];h[O]=function(){Fe.apply(h,arguments),b&&(U=!1,Y.search=h.toString(),U=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var D=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==D&&(D=this.search,U&&(b=!1,this.searchParams._fromString(this.search),b=!0))}})},a=i.prototype,s=function(c){Object.defineProperty(a,c,{get:function(){return this._anchorElement[c]},set:function(u){this._anchorElement[c]=u},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(c){s(c)}),Object.defineProperty(a,"search",{get:function(){return this._anchorElement.search},set:function(c){this._anchorElement.search=c,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(a,{toString:{get:function(){var c=this;return function(){return c.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(c){this._anchorElement.href=c,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(c){this._anchorElement.pathname=c},enumerable:!0},origin:{get:function(){var c={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],u=this._anchorElement.port!=c&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(u?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(c){},enumerable:!0},username:{get:function(){return""},set:function(c){},enumerable:!0}}),i.createObjectURL=function(c){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(c){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:wr)});var An=bt((Fs,Pt)=>{/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */var un,fn,pn,ln,mn,dn,hn,bn,vn,Rt,Er,gn,yn,xn,tt,Sn,wn,En,On,_n,Tn,Mn,Ln,kt;(function(e){var t=typeof global=="object"?global:typeof self=="object"?self:typeof this=="object"?this:{};typeof define=="function"&&define.amd?define("tslib",["exports"],function(n){e(r(t,r(n)))}):typeof Pt=="object"&&typeof Pt.exports=="object"?e(r(t,r(Pt.exports))):e(r(t));function r(n,o){return n!==t&&(typeof Object.create=="function"?Object.defineProperty(n,"__esModule",{value:!0}):n.__esModule=!0),function(i,a){return n[i]=o?o(i,a):a}}})(function(e){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])};un=function(n,o){if(typeof o!="function"&&o!==null)throw new TypeError("Class extends value "+String(o)+" is not a constructor or null");t(n,o);function i(){this.constructor=n}n.prototype=o===null?Object.create(o):(i.prototype=o.prototype,new i)},fn=Object.assign||function(n){for(var o,i=1,a=arguments.length;i=0;f--)(u=n[f])&&(c=(s<3?u(c):s>3?u(o,i,c):u(o,i))||c);return s>3&&c&&Object.defineProperty(o,i,c),c},mn=function(n,o){return function(i,a){o(i,a,n)}},dn=function(n,o){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(n,o)},hn=function(n,o,i,a){function s(c){return c instanceof i?c:new i(function(u){u(c)})}return new(i||(i=Promise))(function(c,u){function f(d){try{l(a.next(d))}catch(h){u(h)}}function p(d){try{l(a.throw(d))}catch(h){u(h)}}function l(d){d.done?c(d.value):s(d.value).then(f,p)}l((a=a.apply(n,o||[])).next())})},bn=function(n,o){var i={label:0,sent:function(){if(c[0]&1)throw c[1];return c[1]},trys:[],ops:[]},a,s,c,u;return u={next:f(0),throw:f(1),return:f(2)},typeof Symbol=="function"&&(u[Symbol.iterator]=function(){return this}),u;function f(l){return function(d){return p([l,d])}}function p(l){if(a)throw new TypeError("Generator is already executing.");for(;i;)try{if(a=1,s&&(c=l[0]&2?s.return:l[0]?s.throw||((c=s.return)&&c.call(s),0):s.next)&&!(c=c.call(s,l[1])).done)return c;switch(s=0,c&&(l=[l[0]&2,c.value]),l[0]){case 0:case 1:c=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,s=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(c=i.trys,!(c=c.length>0&&c[c.length-1])&&(l[0]===6||l[0]===2)){i=0;continue}if(l[0]===3&&(!c||l[1]>c[0]&&l[1]=n.length&&(n=void 0),{value:n&&n[a++],done:!n}}};throw new TypeError(o?"Object is not iterable.":"Symbol.iterator is not defined.")},Er=function(n,o){var i=typeof Symbol=="function"&&n[Symbol.iterator];if(!i)return n;var a=i.call(n),s,c=[],u;try{for(;(o===void 0||o-- >0)&&!(s=a.next()).done;)c.push(s.value)}catch(f){u={error:f}}finally{try{s&&!s.done&&(i=a.return)&&i.call(a)}finally{if(u)throw u.error}}return c},gn=function(){for(var n=[],o=0;o1||f(b,U)})})}function f(b,U){try{p(a[b](U))}catch(Y){h(c[0][3],Y)}}function p(b){b.value instanceof tt?Promise.resolve(b.value.v).then(l,d):h(c[0][2],b)}function l(b){f("next",b)}function d(b){f("throw",b)}function h(b,U){b(U),c.shift(),c.length&&f(c[0][0],c[0][1])}},wn=function(n){var o,i;return o={},a("next"),a("throw",function(s){throw s}),a("return"),o[Symbol.iterator]=function(){return this},o;function a(s,c){o[s]=n[s]?function(u){return(i=!i)?{value:tt(n[s](u)),done:s==="return"}:c?c(u):u}:c}},En=function(n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var o=n[Symbol.asyncIterator],i;return o?o.call(n):(n=typeof Rt=="function"?Rt(n):n[Symbol.iterator](),i={},a("next"),a("throw"),a("return"),i[Symbol.asyncIterator]=function(){return this},i);function a(c){i[c]=n[c]&&function(u){return new Promise(function(f,p){u=n[c](u),s(f,p,u.done,u.value)})}}function s(c,u,f,p){Promise.resolve(p).then(function(l){c({value:l,done:f})},u)}},On=function(n,o){return Object.defineProperty?Object.defineProperty(n,"raw",{value:o}):n.raw=o,n};var r=Object.create?function(n,o){Object.defineProperty(n,"default",{enumerable:!0,value:o})}:function(n,o){n.default=o};_n=function(n){if(n&&n.__esModule)return n;var o={};if(n!=null)for(var i in n)i!=="default"&&Object.prototype.hasOwnProperty.call(n,i)&&kt(o,n,i);return r(o,n),o},Tn=function(n){return n&&n.__esModule?n:{default:n}},Mn=function(n,o,i,a){if(i==="a"&&!a)throw new TypeError("Private accessor was defined without a getter");if(typeof o=="function"?n!==o||!a:!o.has(n))throw new TypeError("Cannot read private member from an object whose class did not declare it");return i==="m"?a:i==="a"?a.call(n):a?a.value:o.get(n)},Ln=function(n,o,i,a,s){if(a==="m")throw new TypeError("Private method is not writable");if(a==="a"&&!s)throw new TypeError("Private accessor was defined without a setter");if(typeof o=="function"?n!==o||!s:!o.has(n))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a==="a"?s.call(n,i):s?s.value=i:o.set(n,i),i},e("__extends",un),e("__assign",fn),e("__rest",pn),e("__decorate",ln),e("__param",mn),e("__metadata",dn),e("__awaiter",hn),e("__generator",bn),e("__exportStar",vn),e("__createBinding",kt),e("__values",Rt),e("__read",Er),e("__spread",gn),e("__spreadArrays",yn),e("__spreadArray",xn),e("__await",tt),e("__asyncGenerator",Sn),e("__asyncDelegator",wn),e("__asyncValues",En),e("__makeTemplateObject",On),e("__importStar",_n),e("__importDefault",Tn),e("__classPrivateFieldGet",Mn),e("__classPrivateFieldSet",Ln)})});var Qr=bt((Tt,qr)=>{/*! + * clipboard.js v2.0.10 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Tt=="object"&&typeof qr=="object"?qr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Tt=="object"?Tt.ClipboardJS=r():t.ClipboardJS=r()})(Tt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return Zi}});var a=i(279),s=i.n(a),c=i(370),u=i.n(c),f=i(817),p=i.n(f);function l($){try{return document.execCommand($)}catch(M){return!1}}var d=function(M){var w=p()(M);return l("cut"),w},h=d;function b($){var M=document.documentElement.getAttribute("dir")==="rtl",w=document.createElement("textarea");w.style.fontSize="12pt",w.style.border="0",w.style.padding="0",w.style.margin="0",w.style.position="absolute",w.style[M?"right":"left"]="-9999px";var W=window.pageYOffset||document.documentElement.scrollTop;return w.style.top="".concat(W,"px"),w.setAttribute("readonly",""),w.value=$,w}var U=function(M){var w=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},W="";if(typeof M=="string"){var R=b(M);w.container.appendChild(R),W=p()(R),l("copy"),R.remove()}else W=p()(M),l("copy");return W},Y=U;function D($){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?D=function(w){return typeof w}:D=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},D($)}var O=function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},w=M.action,W=w===void 0?"copy":w,R=M.container,z=M.target,Oe=M.text;if(W!=="copy"&&W!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(z!==void 0)if(z&&D(z)==="object"&&z.nodeType===1){if(W==="copy"&&z.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(W==="cut"&&(z.hasAttribute("readonly")||z.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Oe)return Y(Oe,{container:R});if(z)return W==="cut"?h(z):Y(z,{container:R})},Fe=O;function he($){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?he=function(w){return typeof w}:he=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},he($)}function et($,M){if(!($ instanceof M))throw new TypeError("Cannot call a class as a function")}function tn($,M){for(var w=0;w0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof R.action=="function"?R.action:this.defaultAction,this.target=typeof R.target=="function"?R.target:this.defaultTarget,this.text=typeof R.text=="function"?R.text:this.defaultText,this.container=he(R.container)==="object"?R.container:document.body}},{key:"listenClick",value:function(R){var z=this;this.listener=u()(R,"click",function(Oe){return z.onClick(Oe)})}},{key:"onClick",value:function(R){var z=R.delegateTarget||R.currentTarget,Oe=this.action(z)||"copy",At=Fe({action:Oe,container:this.container,target:this.target(z),text:this.text(z)});this.emit(At?"success":"error",{action:Oe,text:At,trigger:z,clearSelection:function(){z&&z.focus(),document.activeElement.blur(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(R){return gr("action",R)}},{key:"defaultTarget",value:function(R){var z=gr("target",R);if(z)return document.querySelector(z)}},{key:"defaultText",value:function(R){return gr("text",R)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(R){var z=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return Y(R,z)}},{key:"cut",value:function(R){return h(R)}},{key:"isSupported",value:function(){var R=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],z=typeof R=="string"?[R]:R,Oe=!!document.queryCommandSupported;return z.forEach(function(At){Oe=Oe&&!!document.queryCommandSupported(At)}),Oe}}]),w}(s()),Zi=Xi},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,c){for(;s&&s.nodeType!==o;){if(typeof s.matches=="function"&&s.matches(c))return s;s=s.parentNode}}n.exports=a},438:function(n,o,i){var a=i(828);function s(f,p,l,d,h){var b=u.apply(this,arguments);return f.addEventListener(l,b,h),{destroy:function(){f.removeEventListener(l,b,h)}}}function c(f,p,l,d,h){return typeof f.addEventListener=="function"?s.apply(null,arguments):typeof l=="function"?s.bind(null,document).apply(null,arguments):(typeof f=="string"&&(f=document.querySelectorAll(f)),Array.prototype.map.call(f,function(b){return s(b,p,l,d,h)}))}function u(f,p,l,d){return function(h){h.delegateTarget=a(h.target,p),h.delegateTarget&&d.call(f,h)}}n.exports=c},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(n,o,i){var a=i(879),s=i(438);function c(l,d,h){if(!l&&!d&&!h)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(h))throw new TypeError("Third argument must be a Function");if(a.node(l))return u(l,d,h);if(a.nodeList(l))return f(l,d,h);if(a.string(l))return p(l,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function u(l,d,h){return l.addEventListener(d,h),{destroy:function(){l.removeEventListener(d,h)}}}function f(l,d,h){return Array.prototype.forEach.call(l,function(b){b.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(l,function(b){b.removeEventListener(d,h)})}}}function p(l,d,h){return s(document.body,l,d,h)}n.exports=c},817:function(n){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),u=document.createRange();u.selectNodeContents(i),c.removeAllRanges(),c.addRange(u),a=c.toString()}return a}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,a,s){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var c=this;function u(){c.off(i,u),a.apply(s,arguments)}return u._=a,this.on(i,u,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),c=0,u=s.length;for(c;c{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var ys=/["'&<>]/;gi.exports=xs;function xs(e){var t=""+e,r=ys.exec(t);if(!r)return t;var n,o="",i=0,a=0;for(i=r.index;i0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,a=o.isStopped,s=o.observers;return i||a?Or:(this.currentObservers=null,s.push(r),new Ae(function(){n.currentObservers=null,ke(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,a=n.isStopped;o?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new H;return r.source=this,r},t.create=function(r,n){return new Vn(r,n)},t}(H);var Vn=function(e){ee(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Or},t}(E);var gt={now:function(){return(gt.delegate||Date).now()},delegate:void 0};var yt=function(e){ee(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=gt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,a=n._infiniteTimeWindow,s=n._timestampProvider,c=n._windowTime;o||(i.push(r),!a&&i.push(s.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,a=o._buffer,s=a.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=at.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){if(o===void 0&&(o=0),o!=null&&o>0||o==null&&this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);r.actions.some(function(i){return i.id===n})||(at.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Wt);var qn=function(e){ee(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Vt);var Te=new qn(zn);var k=new H(function(e){return e.complete()});function Nt(e){return e&&_(e.schedule)}function Rr(e){return e[e.length-1]}function Ue(e){return _(Rr(e))?e.pop():void 0}function ye(e){return Nt(Rr(e))?e.pop():void 0}function zt(e,t){return typeof Rr(e)=="number"?e.pop():t}var st=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function qt(e){return _(e==null?void 0:e.then)}function Qt(e){return _(e[it])}function Yt(e){return Symbol.asyncIterator&&_(e==null?void 0:e[Symbol.asyncIterator])}function Kt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function ma(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Bt=ma();function Gt(e){return _(e==null?void 0:e[Bt])}function Jt(e){return kn(this,arguments,function(){var r,n,o,i;return Ht(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,It(r.read())];case 3:return n=a.sent(),o=n.value,i=n.done,i?[4,It(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,It(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Xt(e){return _(e==null?void 0:e.getReader)}function N(e){if(e instanceof H)return e;if(e!=null){if(Qt(e))return da(e);if(st(e))return ha(e);if(qt(e))return ba(e);if(Yt(e))return Qn(e);if(Gt(e))return va(e);if(Xt(e))return ga(e)}throw Kt(e)}function da(e){return new H(function(t){var r=e[it]();if(_(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function ha(e){return new H(function(t){for(var r=0;r=2,!0))}function ae(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new E}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,c=s===void 0?!0:s;return function(u){var f=null,p=null,l=null,d=0,h=!1,b=!1,U=function(){p==null||p.unsubscribe(),p=null},Y=function(){U(),f=l=null,h=b=!1},D=function(){var O=f;Y(),O==null||O.unsubscribe()};return v(function(O,Fe){d++,!b&&!h&&U();var he=l=l!=null?l:r();Fe.add(function(){d--,d===0&&!b&&!h&&(p=jr(D,c))}),he.subscribe(Fe),f||(f=new ot({next:function(et){return he.next(et)},error:function(et){b=!0,U(),p=jr(Y,o,et),he.error(et)},complete:function(){h=!0,U(),p=jr(Y,a),he.complete()}}),re(O).subscribe(f))})(u)}}function jr(e,t){for(var r=[],n=2;ne.next(document)),e}function G(e,t=document){return Array.from(t.querySelectorAll(e))}function Q(e,t=document){let r=fe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function fe(e,t=document){return t.querySelector(e)||void 0}function Ve(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function rr(e){return C(y(document.body,"focusin"),y(document.body,"focusout")).pipe(Je(1),m(()=>{let t=Ve();return typeof t!="undefined"?e.contains(t):!1}),q(e===Ve()),B())}function Ne(e){return{x:e.offsetLeft,y:e.offsetTop}}function mo(e){return C(y(window,"load"),y(window,"resize")).pipe(He(0,Te),m(()=>Ne(e)),q(Ne(e)))}function ho(e){return{x:e.scrollLeft,y:e.scrollTop}}function nr(e){return C(y(e,"scroll"),y(window,"resize")).pipe(He(0,Te),m(()=>ho(e)),q(ho(e)))}var vo=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!Vr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Da?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!Vr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=Ua.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),go=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),xo=typeof WeakMap!="undefined"?new WeakMap:new vo,So=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=Wa.getInstance(),n=new Ja(t,r,this);xo.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){So.prototype[e]=function(){var t;return(t=xo.get(this))[e].apply(t,arguments)}});var Xa=function(){return typeof or.ResizeObserver!="undefined"?or.ResizeObserver:So}(),wo=Xa;var Eo=new E,Za=I(()=>P(new wo(e=>{for(let t of e)Eo.next(t)}))).pipe(x(e=>C(xe,P(e)).pipe(L(()=>e.disconnect()))),X(1));function Ce(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){return Za.pipe(S(t=>t.observe(e)),x(t=>Eo.pipe(T(({target:r})=>r===e),L(()=>t.unobserve(e)),m(()=>Ce(e)))),q(Ce(e)))}function sr(e){return{width:e.scrollWidth,height:e.scrollHeight}}var Oo=new E,es=I(()=>P(new IntersectionObserver(e=>{for(let t of e)Oo.next(t)},{threshold:0}))).pipe(x(e=>C(xe,P(e)).pipe(L(()=>e.disconnect()))),X(1));function _o(e){return es.pipe(S(t=>t.observe(e)),x(t=>Oo.pipe(T(({target:r})=>r===e),L(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function To(e,t=16){return nr(e).pipe(m(({y:r})=>{let n=Ce(e),o=sr(e);return r>=o.height-n.height-t}),B())}var cr={drawer:Q("[data-md-toggle=drawer]"),search:Q("[data-md-toggle=search]")};function Mo(e){return cr[e].checked}function ze(e,t){cr[e].checked!==t&&cr[e].click()}function lt(e){let t=cr[e];return y(t,"change").pipe(m(()=>t.checked),q(t.checked))}function ts(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Lo(){return y(window,"keydown").pipe(T(e=>!(e.metaKey||e.ctrlKey)),m(e=>({mode:Mo("search")?"search":"global",type:e.key,claim(){e.preventDefault(),e.stopPropagation()}})),T(({mode:e,type:t})=>{if(e==="global"){let r=Ve();if(typeof r!="undefined")return!ts(r,t)}return!0}),ae())}function Se(){return new URL(location.href)}function ur(e){location.href=e.href}function Ao(){return new E}function Co(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Co(e,r)}function A(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="boolean"?n.setAttribute(o,t[o]):t[o]&&n.setAttribute(o,"");for(let o of r)Co(n,o);return n}function Ro(e,t){let r=t;if(e.length>r){for(;e[r]!==" "&&--r>0;);return`${e.substring(0,r)}...`}return e}function fr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function ko(){return location.hash.substring(1)}function Po(e){let t=A("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function rs(){return y(window,"hashchange").pipe(m(ko),q(ko()),T(e=>e.length>0),X(1))}function Ho(){return rs().pipe(m(e=>fe(`[id="${e}"]`)),T(e=>typeof e!="undefined"))}function Nr(e){let t=matchMedia(e);return er(r=>t.addListener(()=>r(t.matches))).pipe(q(t.matches))}function Io(){let e=matchMedia("print");return C(y(window,"beforeprint").pipe(m(()=>!0)),y(window,"afterprint").pipe(m(()=>!1))).pipe(q(e.matches))}function zr(e,t){return e.pipe(x(r=>r?t():k))}function pr(e,t={credentials:"same-origin"}){return re(fetch(`${e}`,t)).pipe(ie(()=>k),x(r=>r.status!==200?St(()=>new Error(r.statusText)):P(r)))}function Re(e,t){return pr(e,t).pipe(x(r=>r.json()),X(1))}function $o(e,t){let r=new DOMParser;return pr(e,t).pipe(x(n=>n.text()),m(n=>r.parseFromString(n,"text/xml")),X(1))}function jo(e){let t=A("script",{src:e});return I(()=>(document.head.appendChild(t),C(y(t,"load"),y(t,"error").pipe(x(()=>St(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),L(()=>document.head.removeChild(t)),te(1))))}function Fo(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function Uo(){return C(y(window,"scroll",{passive:!0}),y(window,"resize",{passive:!0})).pipe(m(Fo),q(Fo()))}function Do(){return{width:innerWidth,height:innerHeight}}function Wo(){return y(window,"resize",{passive:!0}).pipe(m(Do),q(Do()))}function Vo(){return K([Uo(),Wo()]).pipe(m(([e,t])=>({offset:e,size:t})),X(1))}function lr(e,{viewport$:t,header$:r}){let n=t.pipe(J("size")),o=K([n,r]).pipe(m(()=>Ne(e)));return K([r,t,o]).pipe(m(([{height:i},{offset:a,size:s},{x:c,y:u}])=>({offset:{x:a.x-c,y:a.y-u+i},size:s})))}function No(e,{tx$:t}){let r=y(e,"message").pipe(m(({data:n})=>n));return t.pipe(_t(()=>r,{leading:!0,trailing:!0}),S(n=>e.postMessage(n)),x(()=>r),ae())}var ns=Q("#__config"),mt=JSON.parse(ns.textContent);mt.base=`${new URL(mt.base,Se())}`;function de(){return mt}function ce(e){return mt.features.includes(e)}function Z(e,t){return typeof t!="undefined"?mt.translations[e].replace("#",t.toString()):mt.translations[e]}function we(e,t=document){return Q(`[data-md-component=${e}]`,t)}function ne(e,t=document){return G(`[data-md-component=${e}]`,t)}var ei=Qe(Qr());function zo(e){return A("aside",{class:"md-annotation",tabIndex:0},A("div",{class:"md-annotation__inner md-tooltip"},A("div",{class:"md-tooltip__inner md-typeset"})),A("span",{class:"md-annotation__index"},A("span",{"data-md-annotation-id":e})))}function qo(e){return A("button",{class:"md-clipboard md-icon",title:Z("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Yr(e,t){let r=t&2,n=t&1,o=Object.keys(e.terms).filter(a=>!e.terms[a]).reduce((a,s)=>[...a,A("del",null,s)," "],[]).slice(0,-1),i=new URL(e.location);return ce("search.highlight")&&i.searchParams.set("h",Object.entries(e.terms).filter(([,a])=>a).reduce((a,[s])=>`${a} ${s}`.trim(),"")),A("a",{href:`${i}`,class:"md-search-result__link",tabIndex:-1},A("article",{class:["md-search-result__article",...r?["md-search-result__article--document"]:[]].join(" "),"data-md-score":e.score.toFixed(2)},r>0&&A("div",{class:"md-search-result__icon md-icon"}),A("h1",{class:"md-search-result__title"},e.title),n>0&&e.text.length>0&&A("p",{class:"md-search-result__teaser"},Ro(e.text,320)),e.tags&&e.tags.map(a=>A("span",{class:"md-tag"},a)),n>0&&o.length>0&&A("p",{class:"md-search-result__terms"},Z("search.result.term.missing"),": ",o)))}function Qo(e){let t=e[0].score,r=[...e],n=r.findIndex(u=>!u.location.includes("#")),[o]=r.splice(n,1),i=r.findIndex(u=>u.scoreYr(u,1)),...s.length?[A("details",{class:"md-search-result__more"},A("summary",{tabIndex:-1},s.length>0&&s.length===1?Z("search.result.more.one"):Z("search.result.more.other",s.length)),s.map(u=>Yr(u,1)))]:[]];return A("li",{class:"md-search-result__item"},c)}function Yo(e){return A("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>A("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?fr(r):r)))}function Ko(e){return A("div",{class:"md-typeset__scrollwrap"},A("div",{class:"md-typeset__table"},e))}function os(e){let t=de(),r=new URL(`../${e.version}/`,t.base);return A("li",{class:"md-version__item"},A("a",{href:r.toString(),class:"md-version__link"},e.title))}function Bo(e,t){return A("div",{class:"md-version"},A("button",{class:"md-version__current","aria-label":Z("select.version.title")},t.title),A("ul",{class:"md-version__list"},e.map(os)))}function is(e,t){let r=I(()=>K([mo(e),nr(t)])).pipe(m(([{x:n,y:o},i])=>{let{width:a}=Ce(e);return{x:n-i.x+a/2,y:o-i.y}}));return rr(e).pipe(x(n=>r.pipe(m(o=>({active:n,offset:o})),te(+!n||1/0))))}function Go(e,t){return I(()=>{let r=new E;r.subscribe({next({offset:i}){e.style.setProperty("--md-tooltip-x",`${i.x}px`),e.style.setProperty("--md-tooltip-y",`${i.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),r.pipe(Dr(500,Te),m(()=>t.getBoundingClientRect()),m(({x:i})=>i)).subscribe({next(i){i?e.style.setProperty("--md-tooltip-0",`${-i}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}});let n=Q(":scope > :last-child",e),o=y(n,"mousedown",{once:!0});return r.pipe(x(({active:i})=>i?o:k),S(i=>i.preventDefault())).subscribe(()=>e.blur()),is(e,t).pipe(S(i=>r.next(i)),L(()=>r.complete()),m(i=>j({ref:e},i)))})}function as(e){let t=[];for(let r of G(".c, .c1, .cm",e)){let n,o=r.firstChild;if(o instanceof Text)for(;n=/\((\d+)\)/.exec(o.textContent);){let i=o.splitText(n.index);o=i.splitText(n[0].length),t.push(i)}}return t}function Jo(e,t){t.append(...Array.from(e.childNodes))}function Xo(e,t,{print$:r}){let n=new Map;for(let o of as(t)){let[,i]=o.textContent.match(/\((\d+)\)/);fe(`li:nth-child(${i})`,e)&&(n.set(+i,zo(+i)),o.replaceWith(n.get(+i)))}return n.size===0?k:I(()=>{let o=new E;return r.pipe(se(o.pipe(le(1)))).subscribe(i=>{e.hidden=!i;for(let[a,s]of n){let c=Q(".md-typeset",s),u=Q(`li:nth-child(${a})`,e);i?Jo(c,u):Jo(u,c)}}),C(...[...n].map(([,i])=>Go(i,t))).pipe(L(()=>o.complete()),ae())})}var ss=0;function ti(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return ti(t)}}function Zo(e){return ge(e).pipe(m(({width:t})=>({scrollable:sr(e).width>t})),J("scrollable"))}function ri(e,t){let{matches:r}=matchMedia("(hover)"),n=I(()=>{let o=new E;if(o.subscribe(({scrollable:a})=>{a&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")}),ei.default.isSupported()){let a=e.closest("pre");a.id=`__code_${++ss}`,a.insertBefore(qo(a.id),e)}let i=e.closest(".highlight");if(i instanceof HTMLElement){let a=ti(i);if(typeof a!="undefined"&&(i.classList.contains("annotate")||ce("content.code.annotate"))){let s=Xo(a,e,t);return Zo(e).pipe(S(c=>o.next(c)),L(()=>o.complete()),m(c=>j({ref:e},c)),Xe(ge(i).pipe(se(o.pipe(le(1))),m(({width:c,height:u})=>c&&u),B(),x(c=>c?s:k))))}}return Zo(e).pipe(S(a=>o.next(a)),L(()=>o.complete()),m(a=>j({ref:e},a)))});return _o(e).pipe(T(o=>o),te(1),x(()=>n))}var ni=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:transparent}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color)}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}defs #flowchart-circleEnd,defs #flowchart-circleStart,defs #flowchart-crossEnd,defs #flowchart-crossStart,defs #flowchart-pointEnd,defs #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}.actor,defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{stroke:var(--md-mermaid-node-fg-color)}text.actor>tspan{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-default-fg-color--lighter)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-edge-color)}.loopText>tspan,.messageText{font-family:var(--md-mermaid-font-family)!important}#arrowhead path,.loopText>tspan,.messageText{fill:var(--md-mermaid-edge-color);stroke:none}.loopLine{stroke:var(--md-mermaid-node-fg-color)}.labelBox,.loopLine{fill:var(--md-mermaid-node-bg-color)}.labelBox{stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-node-fg-color);font-family:var(--md-mermaid-font-family)}";var Kr,us=0;function fs(){return typeof mermaid=="undefined"||mermaid instanceof Element?jo("https://unpkg.com/mermaid@9.0.1/dist/mermaid.min.js"):P(void 0)}function oi(e){return e.classList.remove("mermaid"),Kr||(Kr=fs().pipe(S(()=>mermaid.initialize({startOnLoad:!1,themeCSS:ni})),m(()=>{}),X(1))),Kr.subscribe(()=>{e.classList.add("mermaid");let t=`__mermaid_${us++}`,r=A("div",{class:"mermaid"});mermaid.mermaidAPI.render(t,e.textContent,n=>{let o=r.attachShadow({mode:"closed"});o.innerHTML=n,e.replaceWith(r)})}),Kr.pipe(m(()=>({ref:e})))}function ps(e,{target$:t,print$:r}){let n=!0;return C(t.pipe(m(o=>o.closest("details:not([open])")),T(o=>e===o),m(()=>({action:"open",reveal:!0}))),r.pipe(T(o=>o||!n),S(()=>n=e.open),m(o=>({action:o?"open":"close"}))))}function ii(e,t){return I(()=>{let r=new E;return r.subscribe(({action:n,reveal:o})=>{n==="open"?e.setAttribute("open",""):e.removeAttribute("open"),o&&e.scrollIntoView()}),ps(e,t).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>j({ref:e},n)))})}var ai=A("table");function si(e){return e.replaceWith(ai),ai.replaceWith(Ko(e)),P({ref:e})}function ls(e){let t=G(":scope > input",e),r=t.find(n=>n.checked)||t[0];return C(...t.map(n=>y(n,"change").pipe(m(()=>({active:Q(`label[for=${n.id}]`)}))))).pipe(q({active:Q(`label[for=${r.id}]`)}))}function ci(e){let t=Q(".tabbed-labels",e);return I(()=>{let r=new E;return K([r,ge(e)]).pipe(He(1,Te),se(r.pipe(le(1)))).subscribe({next([{active:n}]){let o=Ne(n),{width:i}=Ce(n);e.style.setProperty("--md-indicator-x",`${o.x}px`),e.style.setProperty("--md-indicator-width",`${i}px`),t.scrollTo({behavior:"smooth",left:o.x})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),ls(e).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>j({ref:e},n)))}).pipe(Ke(ue))}function ui(e,{target$:t,print$:r}){return C(...G("pre:not(.mermaid) > code",e).map(n=>ri(n,{print$:r})),...G("pre.mermaid",e).map(n=>oi(n)),...G("table:not([class])",e).map(n=>si(n)),...G("details",e).map(n=>ii(n,{target$:t,print$:r})),...G("[data-tabs]",e).map(n=>ci(n)))}function ms(e,{alert$:t}){return t.pipe(x(r=>C(P(!0),P(!1).pipe($e(2e3))).pipe(m(n=>({message:r,active:n})))))}function fi(e,t){let r=Q(".md-typeset",e);return I(()=>{let n=new E;return n.subscribe(({message:o,active:i})=>{r.textContent=o,i?e.setAttribute("data-md-state","open"):e.removeAttribute("data-md-state")}),ms(e,t).pipe(S(o=>n.next(o)),L(()=>n.complete()),m(o=>j({ref:e},o)))})}function ds({viewport$:e}){if(!ce("header.autohide"))return P(!1);let t=e.pipe(m(({offset:{y:o}})=>o),Me(2,1),m(([o,i])=>[oMath.abs(i-o.y)>100),m(([,[o]])=>o),B()),n=lt("search");return K([e,n]).pipe(m(([{offset:o},i])=>o.y>400&&!i),B(),x(o=>o?r:P(!1)),q(!1))}function pi(e,t){return I(()=>K([ge(e),ds(t)])).pipe(m(([{height:r},n])=>({height:r,hidden:n})),B((r,n)=>r.height===n.height&&r.hidden===n.hidden),X(1))}function li(e,{header$:t,main$:r}){return I(()=>{let n=new E;return n.pipe(J("active"),Ge(t)).subscribe(([{active:o},{hidden:i}])=>{o?e.setAttribute("data-md-state",i?"hidden":"shadow"):e.removeAttribute("data-md-state")}),r.subscribe(n),t.pipe(se(n.pipe(le(1))),m(o=>j({ref:e},o)))})}function hs(e,{viewport$:t,header$:r}){return lr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:n}})=>{let{height:o}=Ce(e);return{active:n>=o}}),J("active"))}function mi(e,t){return I(()=>{let r=new E;r.subscribe(({active:o})=>{o?e.setAttribute("data-md-state","active"):e.removeAttribute("data-md-state")});let n=fe("article h1");return typeof n=="undefined"?k:hs(n,t).pipe(S(o=>r.next(o)),L(()=>r.complete()),m(o=>j({ref:e},o)))})}function di(e,{viewport$:t,header$:r}){let n=r.pipe(m(({height:i})=>i),B()),o=n.pipe(x(()=>ge(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),J("bottom"))));return K([n,o,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:c},size:{height:u}}])=>(u=Math.max(0,u-Math.max(0,a-c,i)-Math.max(0,u+c-s)),{offset:a-i,height:u,active:a-i<=c})),B((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function bs(e){let t=__md_get("__palette")||{index:e.findIndex(r=>matchMedia(r.getAttribute("data-md-color-media")).matches)};return P(...e).pipe(oe(r=>y(r,"change").pipe(m(()=>r))),q(e[Math.max(0,t.index)]),m(r=>({index:e.indexOf(r),color:{scheme:r.getAttribute("data-md-color-scheme"),primary:r.getAttribute("data-md-color-primary"),accent:r.getAttribute("data-md-color-accent")}})),X(1))}function hi(e){return I(()=>{let t=new E;t.subscribe(n=>{document.body.setAttribute("data-md-color-switching","");for(let[o,i]of Object.entries(n.color))document.body.setAttribute(`data-md-color-${o}`,i);for(let o=0;o{document.body.removeAttribute("data-md-color-switching")});let r=G("input",e);return bs(r).pipe(S(n=>t.next(n)),L(()=>t.complete()),m(n=>j({ref:e},n)))})}var Br=Qe(Qr());function vs(e){e.setAttribute("data-md-copying","");let t=e.innerText;return e.removeAttribute("data-md-copying"),t}function bi({alert$:e}){Br.default.isSupported()&&new H(t=>{new Br.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||vs(Q(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(S(t=>{t.trigger.focus()}),m(()=>Z("clipboard.copied"))).subscribe(e)}function gs(e){if(e.length<2)return[""];let[t,r]=[...e].sort((o,i)=>o.length-i.length).map(o=>o.replace(/[^/]+$/,"")),n=0;if(t===r)n=t.length;else for(;t.charCodeAt(n)===r.charCodeAt(n);)n++;return e.map(o=>o.replace(t.slice(0,n),""))}function mr(e){let t=__md_get("__sitemap",sessionStorage,e);if(t)return P(t);{let r=de();return $o(new URL("sitemap.xml",e||r.base)).pipe(m(n=>gs(G("loc",n).map(o=>o.textContent))),ie(()=>k),Ie([]),S(n=>__md_set("__sitemap",n,sessionStorage,e)))}}function vi({document$:e,location$:t,viewport$:r}){let n=de();if(location.protocol==="file:")return;"scrollRestoration"in history&&(history.scrollRestoration="manual",y(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}));let o=fe("link[rel=icon]");typeof o!="undefined"&&(o.href=o.href);let i=mr().pipe(m(u=>u.map(f=>`${new URL(f,n.base)}`)),x(u=>y(document.body,"click").pipe(T(f=>!f.metaKey&&!f.ctrlKey),x(f=>{if(f.target instanceof Element){let p=f.target.closest("a");if(p&&!p.target){let l=new URL(p.href);if(l.search="",l.hash="",l.pathname!==location.pathname&&u.includes(l.toString()))return f.preventDefault(),P({url:new URL(p.href)})}}return xe}))),ae()),a=y(window,"popstate").pipe(T(u=>u.state!==null),m(u=>({url:new URL(location.href),offset:u.state})),ae());C(i,a).pipe(B((u,f)=>u.url.href===f.url.href),m(({url:u})=>u)).subscribe(t);let s=t.pipe(J("pathname"),x(u=>pr(u.href).pipe(ie(()=>(ur(u),xe)))),ae());i.pipe(ft(s)).subscribe(({url:u})=>{history.pushState({},"",`${u}`)});let c=new DOMParser;s.pipe(x(u=>u.text()),m(u=>c.parseFromString(u,"text/html"))).subscribe(e),e.pipe(je(1)).subscribe(u=>{for(let f of["title","link[rel=canonical]","meta[name=author]","meta[name=description]","[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...ce("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let p=fe(f),l=fe(f,u);typeof p!="undefined"&&typeof l!="undefined"&&p.replaceWith(l)}}),e.pipe(je(1),m(()=>we("container")),x(u=>G("script",u)),Hr(u=>{let f=A("script");if(u.src){for(let p of u.getAttributeNames())f.setAttribute(p,u.getAttribute(p));return u.replaceWith(f),new H(p=>{f.onload=()=>p.complete()})}else return f.textContent=u.textContent,u.replaceWith(f),k})).subscribe(),C(i,a).pipe(ft(e)).subscribe(({url:u,offset:f})=>{u.hash&&!f?Po(u.hash):window.scrollTo(0,(f==null?void 0:f.y)||0)}),r.pipe(Ot(i),Je(250),J("offset")).subscribe(({offset:u})=>{history.replaceState(u,"")}),C(i,a).pipe(Me(2,1),T(([u,f])=>u.url.pathname===f.url.pathname),m(([,u])=>u)).subscribe(({offset:u})=>{window.scrollTo(0,(u==null?void 0:u.y)||0)})}var Ss=Qe(Gr());var yi=Qe(Gr());function Jr(e,t){let r=new RegExp(e.separator,"img"),n=(o,i,a)=>`${i}${a}`;return o=>{o=o.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator})(${o.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(t?(0,yi.default)(a):a).replace(i,n).replace(/<\/mark>(\s+)]*>/img,"$1")}}function xi(e){return e.split(/"([^"]+)"/g).map((t,r)=>r&1?t.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):t).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").trim()}function dt(e){return e.type===1}function Si(e){return e.type===2}function ht(e){return e.type===3}function Es({config:e,docs:t}){e.lang.length===1&&e.lang[0]==="en"&&(e.lang=[Z("search.config.lang")]),e.separator==="[\\s\\-]+"&&(e.separator=Z("search.config.separator"));let n={pipeline:Z("search.config.pipeline").split(/\s*,\s*/).filter(Boolean),suggestions:ce("search.suggest")};return{config:e,docs:t,options:n}}function wi(e,t){let r=de(),n=new Worker(e),o=new E,i=No(n,{tx$:o}).pipe(m(a=>{if(ht(a))for(let s of a.data.items)for(let c of s)c.location=`${new URL(c.location,r.base)}`;return a}),ae());return re(t).pipe(m(a=>({type:0,data:Es(a)}))).subscribe(o.next.bind(o)),{tx$:o,rx$:i}}function Ei({document$:e}){let t=de(),r=Re(new URL("../versions.json",t.base)).pipe(ie(()=>k)),n=r.pipe(m(o=>{let[,i]=t.base.match(/([^/]+)\/?$/);return o.find(({version:a,aliases:s})=>a===i||s.includes(i))||o[0]}));K([r,n]).pipe(m(([o,i])=>new Map(o.filter(a=>a!==i).map(a=>[`${new URL(`../${a.version}/`,t.base)}`,a]))),x(o=>y(document.body,"click").pipe(T(i=>!i.metaKey&&!i.ctrlKey),x(i=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&o.has(a.href))return i.preventDefault(),P(a.href)}return k}),x(i=>{let{version:a}=o.get(i);return mr(new URL(i)).pipe(m(s=>{let u=Se().href.replace(t.base,"");return s.includes(u)?new URL(`../${a}/${u}`,t.base):new URL(i)}))})))).subscribe(o=>ur(o)),K([r,n]).subscribe(([o,i])=>{Q(".md-header__topic").appendChild(Bo(o,i))}),e.pipe(x(()=>n)).subscribe(o=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){let s=((a=t.version)==null?void 0:a.default)||"latest";i=!o.aliases.includes(s),__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ne("outdated"))s.hidden=!1})}function Os(e,{rx$:t}){let r=(__search==null?void 0:__search.transform)||xi,{searchParams:n}=Se();n.has("q")&&ze("search",!0);let o=t.pipe(T(dt),te(1),m(()=>n.get("q")||""));lt("search").pipe(T(s=>!s),te(1)).subscribe(()=>{let s=new URL(location.href);s.searchParams.delete("q"),history.replaceState({},"",`${s}`)}),o.subscribe(s=>{s&&(e.value=s,e.focus())});let i=rr(e),a=C(y(e,"keyup"),y(e,"focus").pipe($e(1)),o).pipe(m(()=>r(e.value)),q(""),B());return K([a,i]).pipe(m(([s,c])=>({value:s,focus:c})),X(1))}function Oi(e,{tx$:t,rx$:r}){let n=new E;return n.pipe(J("value"),m(({value:o})=>({type:2,data:o}))).subscribe(t.next.bind(t)),n.pipe(J("focus")).subscribe(({focus:o})=>{o?(ze("search",o),e.placeholder=""):e.placeholder=Z("search.placeholder")}),y(e.form,"reset").pipe(se(n.pipe(le(1)))).subscribe(()=>e.focus()),Os(e,{tx$:t,rx$:r}).pipe(S(o=>n.next(o)),L(()=>n.complete()),m(o=>j({ref:e},o)))}function _i(e,{rx$:t},{query$:r}){let n=new E,o=To(e.parentElement).pipe(T(Boolean)),i=Q(":scope > :first-child",e),a=Q(":scope > :last-child",e),s=t.pipe(T(dt),te(1));return n.pipe(Le(r),Ot(s)).subscribe(([{items:u},{value:f}])=>{if(f)switch(u.length){case 0:i.textContent=Z("search.result.none");break;case 1:i.textContent=Z("search.result.one");break;default:i.textContent=Z("search.result.other",fr(u.length))}else i.textContent=Z("search.result.placeholder")}),n.pipe(S(()=>a.innerHTML=""),x(({items:u})=>C(P(...u.slice(0,10)),P(...u.slice(10)).pipe(Me(4),Wr(o),x(([f])=>f))))).subscribe(u=>a.appendChild(Qo(u))),t.pipe(T(ht),m(({data:u})=>u)).pipe(S(u=>n.next(u)),L(()=>n.complete()),m(u=>j({ref:e},u)))}function _s(e,{query$:t}){return t.pipe(m(({value:r})=>{let n=Se();return n.hash="",n.searchParams.delete("h"),n.searchParams.set("q",r),{url:n}}))}function Ti(e,t){let r=new E;return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),y(e,"click").subscribe(n=>n.preventDefault()),_s(e,t).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>j({ref:e},n)))}function Mi(e,{rx$:t},{keyboard$:r}){let n=new E,o=we("search-query"),i=C(y(o,"keydown"),y(o,"focus")).pipe(Pe(ue),m(()=>o.value),B());return n.pipe(Ge(i),m(([{suggestions:s},c])=>{let u=c.split(/([\s-]+)/);if((s==null?void 0:s.length)&&u[u.length-1]){let f=s[s.length-1];f.startsWith(u[u.length-1])&&(u[u.length-1]=f)}else u.length=0;return u})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(T(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&o.selectionStart===o.value.length&&(o.value=e.innerText);break}}),t.pipe(T(ht),m(({data:s})=>s)).pipe(S(s=>n.next(s)),L(()=>n.complete()),m(()=>({ref:e})))}function Li(e,{index$:t,keyboard$:r}){let n=de();try{let o=(__search==null?void 0:__search.worker)||n.search,i=wi(o,t),a=we("search-query",e),s=we("search-result",e),{tx$:c,rx$:u}=i;c.pipe(T(Si),ft(u.pipe(T(dt))),te(1)).subscribe(c.next.bind(c)),r.pipe(T(({mode:l})=>l==="search")).subscribe(l=>{let d=Ve();switch(l.type){case"Enter":if(d===a){let h=new Map;for(let b of G(":first-child [href]",s)){let U=b.firstElementChild;h.set(b,parseFloat(U.getAttribute("data-md-score")))}if(h.size){let[[b]]=[...h].sort(([,U],[,Y])=>Y-U);b.click()}l.claim()}break;case"Escape":case"Tab":ze("search",!1),a.blur();break;case"ArrowUp":case"ArrowDown":if(typeof d=="undefined")a.focus();else{let h=[a,...G(":not(details) > [href], summary, details[open] [href]",s)],b=Math.max(0,(Math.max(0,h.indexOf(d))+h.length+(l.type==="ArrowUp"?-1:1))%h.length);h[b].focus()}l.claim();break;default:a!==Ve()&&a.focus()}}),r.pipe(T(({mode:l})=>l==="global")).subscribe(l=>{switch(l.type){case"f":case"s":case"/":a.focus(),a.select(),l.claim();break}});let f=Oi(a,i),p=_i(s,i,{query$:f});return C(f,p).pipe(Xe(...ne("search-share",e).map(l=>Ti(l,{query$:f})),...ne("search-suggest",e).map(l=>Mi(l,i,{keyboard$:r}))))}catch(o){return e.hidden=!0,xe}}function Ai(e,{index$:t,location$:r}){return K([t,r.pipe(q(Se()),T(n=>!!n.searchParams.get("h")))]).pipe(m(([n,o])=>Jr(n.config,!0)(o.searchParams.get("h"))),m(n=>{var a;let o=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let c=s.textContent,u=n(c);u.length>c.length&&o.set(s,u)}for(let[s,c]of o){let{childNodes:u}=A("span",null,c);s.replaceWith(...Array.from(u))}return{ref:e,nodes:o}}))}function Ts(e,{viewport$:t,main$:r}){let n=e.parentElement,o=n.offsetTop-n.parentElement.offsetTop;return K([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(o,Math.max(0,s-i))-o,{height:a,locked:s>=i+o})),B((i,a)=>i.height===a.height&&i.locked===a.locked))}function Xr(e,n){var o=n,{header$:t}=o,r=on(o,["header$"]);let i=Q(".md-sidebar__scrollwrap",e),{y:a}=Ne(i);return I(()=>{let s=new E;return s.pipe(He(0,Te),Le(t)).subscribe({next([{height:c},{height:u}]){i.style.height=`${c-2*a}px`,e.style.top=`${u}px`},complete(){i.style.height="",e.style.top=""}}),Ts(e,r).pipe(S(c=>s.next(c)),L(()=>s.complete()),m(c=>j({ref:e},c)))})}function Ci(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return wt(Re(`${r}/releases/latest`).pipe(ie(()=>k),m(n=>({version:n.tag_name})),Ie({})),Re(r).pipe(ie(()=>k),m(n=>({stars:n.stargazers_count,forks:n.forks_count})),Ie({}))).pipe(m(([n,o])=>j(j({},n),o)))}else{let r=`https://api.github.com/users/${e}`;return Re(r).pipe(m(n=>({repositories:n.public_repos})),Ie({}))}}function Ri(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Re(r).pipe(ie(()=>k),m(({star_count:n,forks_count:o})=>({stars:n,forks:o})),Ie({}))}function ki(e){let[t]=e.match(/(git(?:hub|lab))/i)||[];switch(t.toLowerCase()){case"github":let[,r,n]=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);return Ci(r,n);case"gitlab":let[,o,i]=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i);return Ri(o,i);default:return k}}var Ms;function Ls(e){return Ms||(Ms=I(()=>{let t=__md_get("__source",sessionStorage);return t?P(t):ki(e.href).pipe(S(r=>__md_set("__source",r,sessionStorage)))}).pipe(ie(()=>k),T(t=>Object.keys(t).length>0),m(t=>({facts:t})),X(1)))}function Pi(e){let t=Q(":scope > :last-child",e);return I(()=>{let r=new E;return r.subscribe(({facts:n})=>{t.appendChild(Yo(n)),t.setAttribute("data-md-state","done")}),Ls(e).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>j({ref:e},n)))})}function As(e,{viewport$:t,header$:r}){return ge(document.body).pipe(x(()=>lr(e,{header$:r,viewport$:t})),m(({offset:{y:n}})=>({hidden:n>=10})),J("hidden"))}function Hi(e,t){return I(()=>{let r=new E;return r.subscribe({next({hidden:n}){n?e.setAttribute("data-md-state","hidden"):e.removeAttribute("data-md-state")},complete(){e.removeAttribute("data-md-state")}}),(ce("navigation.tabs.sticky")?P({hidden:!1}):As(e,t)).pipe(S(n=>r.next(n)),L(()=>r.complete()),m(n=>j({ref:e},n)))})}function Cs(e,{viewport$:t,header$:r}){let n=new Map,o=G("[href^=\\#]",e);for(let s of o){let c=decodeURIComponent(s.hash.substring(1)),u=fe(`[id="${c}"]`);typeof u!="undefined"&&n.set(s,u)}let i=r.pipe(J("height"),m(({height:s})=>{let c=we("main"),u=Q(":scope > :first-child",c);return s+.8*(u.offsetTop-c.offsetTop)}),ae());return ge(document.body).pipe(J("height"),x(s=>I(()=>{let c=[];return P([...n].reduce((u,[f,p])=>{for(;c.length&&n.get(c[c.length-1]).tagName>=p.tagName;)c.pop();let l=p.offsetTop;for(;!l&&p.parentElement;)p=p.parentElement,l=p.offsetTop;return u.set([...c=[...c,f]].reverse(),l)},new Map))}).pipe(m(c=>new Map([...c].sort(([,u],[,f])=>u-f))),Ge(i),x(([c,u])=>t.pipe($r(([f,p],{offset:{y:l},size:d})=>{let h=l+d.height>=Math.floor(s.height);for(;p.length;){let[,b]=p[0];if(b-u=l&&!h)p=[f.pop(),...p];else break}return[f,p]},[[],[...c]]),B((f,p)=>f[0]===p[0]&&f[1]===p[1])))))).pipe(m(([s,c])=>({prev:s.map(([u])=>u),next:c.map(([u])=>u)})),q({prev:[],next:[]}),Me(2,1),m(([s,c])=>s.prev.length{let o=new E;return o.subscribe(({prev:i,next:a})=>{for(let[s]of a)s.removeAttribute("data-md-state"),s.classList.remove("md-nav__link--active");for(let[s,[c]]of i.entries())c.setAttribute("data-md-state","blur"),c.classList.toggle("md-nav__link--active",s===i.length-1)}),ce("navigation.tracking")&&t.pipe(se(o.pipe(le(1))),J("offset"),Je(250),je(1),se(n.pipe(je(1))),Et({delay:250}),Le(o)).subscribe(([,{prev:i}])=>{let a=Se(),s=i[i.length-1];if(s&&s.length){let[c]=s,{hash:u}=new URL(c.href);a.hash!==u&&(a.hash=u,history.replaceState({},"",`${a}`))}else a.hash="",history.replaceState({},"",`${a}`)}),Cs(e,{viewport$:t,header$:r}).pipe(S(i=>o.next(i)),L(()=>o.complete()),m(i=>j({ref:e},i)))})}function Rs(e,{viewport$:t,main$:r,target$:n}){let o=t.pipe(m(({offset:{y:a}})=>a),Me(2,1),m(([a,s])=>a>s&&s>0),B()),i=r.pipe(m(({active:a})=>a));return K([i,o]).pipe(m(([a,s])=>!(a&&s)),B(),se(n.pipe(je(1))),tr(!0),Et({delay:250}),m(a=>({hidden:a})))}function $i(e,{viewport$:t,header$:r,main$:n,target$:o}){let i=new E;return i.subscribe({next({hidden:a}){a?(e.setAttribute("data-md-state","hidden"),e.setAttribute("tabindex","-1"),e.blur()):(e.removeAttribute("data-md-state"),e.removeAttribute("tabindex"))},complete(){e.style.top="",e.setAttribute("data-md-state","hidden"),e.removeAttribute("tabindex")}}),r.pipe(se(i.pipe(tr(0),le(1))),J("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),Rs(e,{viewport$:t,main$:n,target$:o}).pipe(S(a=>i.next(a)),L(()=>i.complete()),m(a=>j({ref:e},a)))}function ji({document$:e,tablet$:t}){e.pipe(x(()=>G("[data-md-state=indeterminate]")),S(r=>{r.indeterminate=!0,r.checked=!1}),oe(r=>y(r,"change").pipe(Fr(()=>r.hasAttribute("data-md-state")),m(()=>r))),Le(t)).subscribe(([r,n])=>{r.removeAttribute("data-md-state"),n&&(r.checked=!1)})}function ks(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Fi({document$:e}){e.pipe(x(()=>G("[data-md-scrollfix]")),S(t=>t.removeAttribute("data-md-scrollfix")),T(ks),oe(t=>y(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Ui({viewport$:e,tablet$:t}){K([lt("search"),t]).pipe(m(([r,n])=>r&&!n),x(r=>P(r).pipe($e(r?400:100))),Le(e)).subscribe(([r,{offset:{y:n}}])=>{if(r)document.body.setAttribute("data-md-state","lock"),document.body.style.top=`-${n}px`;else{let o=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-state"),document.body.style.top="",o&&window.scrollTo(0,o)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let n=e[r];typeof n!="object"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?t.insertBefore(this.previousSibling,n):t.replaceChild(n,this)}}}));document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var Ze=lo(),hr=Ao(),Mt=Ho(),Zr=Lo(),Ee=Vo(),br=Nr("(min-width: 960px)"),Wi=Nr("(min-width: 1220px)"),Vi=Io(),Ni=de(),zi=document.forms.namedItem("search")?(__search==null?void 0:__search.index)||Re(new URL("search/search_index.json",Ni.base)):xe,en=new E;bi({alert$:en});ce("navigation.instant")&&vi({document$:Ze,location$:hr,viewport$:Ee});var Di;((Di=Ni.version)==null?void 0:Di.provider)==="mike"&&Ei({document$:Ze});C(hr,Mt).pipe($e(125)).subscribe(()=>{ze("drawer",!1),ze("search",!1)});Zr.pipe(T(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=fe("[href][rel=prev]");typeof t!="undefined"&&t.click();break;case"n":case".":let r=fe("[href][rel=next]");typeof r!="undefined"&&r.click();break}});ji({document$:Ze,tablet$:br});Fi({document$:Ze});Ui({viewport$:Ee,tablet$:br});var qe=pi(we("header"),{viewport$:Ee}),dr=Ze.pipe(m(()=>we("main")),x(e=>di(e,{viewport$:Ee,header$:qe})),X(1)),Ps=C(...ne("dialog").map(e=>fi(e,{alert$:en})),...ne("header").map(e=>li(e,{viewport$:Ee,header$:qe,main$:dr})),...ne("palette").map(e=>hi(e)),...ne("search").map(e=>Li(e,{index$:zi,keyboard$:Zr})),...ne("source").map(e=>Pi(e))),Hs=I(()=>C(...ne("content").map(e=>ui(e,{target$:Mt,print$:Vi})),...ne("content").map(e=>ce("search.highlight")?Ai(e,{index$:zi,location$:hr}):k),...ne("header-title").map(e=>mi(e,{viewport$:Ee,header$:qe})),...ne("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?zr(Wi,()=>Xr(e,{viewport$:Ee,header$:qe,main$:dr})):zr(br,()=>Xr(e,{viewport$:Ee,header$:qe,main$:dr}))),...ne("tabs").map(e=>Hi(e,{viewport$:Ee,header$:qe})),...ne("toc").map(e=>Ii(e,{viewport$:Ee,header$:qe,target$:Mt})),...ne("top").map(e=>$i(e,{viewport$:Ee,header$:qe,main$:dr,target$:Mt})))),qi=Ze.pipe(x(()=>Hs),Xe(Ps),X(1));qi.subscribe();window.document$=Ze;window.location$=hr;window.target$=Mt;window.keyboard$=Zr;window.viewport$=Ee;window.tablet$=br;window.screen$=Wi;window.print$=Vi;window.alert$=en;window.component$=qi;})(); +//# sourceMappingURL=bundle.c2e1ee47.min.js.map + diff --git a/assets/javascripts/bundle.748e2769.min.js.map b/assets/javascripts/bundle.c2e1ee47.min.js.map similarity index 59% rename from assets/javascripts/bundle.748e2769.min.js.map rename to assets/javascripts/bundle.c2e1ee47.min.js.map index 038ab4683..fc013bab6 100644 --- a/assets/javascripts/bundle.748e2769.min.js.map +++ b/assets/javascripts/bundle.c2e1ee47.min.js.map @@ -2,7 +2,7 @@ "version": 3, "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/url-polyfill/url-polyfill.js", "node_modules/rxjs/node_modules/tslib/tslib.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "node_modules/array-flat-polyfill/index.mjs", "src/assets/javascripts/bundle.ts", "node_modules/unfetch/polyfill/index.js", "node_modules/rxjs/node_modules/tslib/modules/index.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/concatMap.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/sample.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/assets/javascripts/browser/document/index.ts", "src/assets/javascripts/browser/element/_/index.ts", "src/assets/javascripts/browser/element/focus/index.ts", "src/assets/javascripts/browser/element/offset/_/index.ts", "src/assets/javascripts/browser/element/offset/content/index.ts", "node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js", "src/assets/javascripts/browser/element/size/_/index.ts", "src/assets/javascripts/browser/element/size/content/index.ts", "src/assets/javascripts/browser/element/visibility/index.ts", "src/assets/javascripts/browser/toggle/index.ts", "src/assets/javascripts/browser/keyboard/index.ts", "src/assets/javascripts/browser/location/_/index.ts", "src/assets/javascripts/utilities/h/index.ts", "src/assets/javascripts/utilities/string/index.ts", "src/assets/javascripts/browser/location/hash/index.ts", "src/assets/javascripts/browser/media/index.ts", "src/assets/javascripts/browser/request/index.ts", "src/assets/javascripts/browser/script/index.ts", "src/assets/javascripts/browser/viewport/offset/index.ts", "src/assets/javascripts/browser/viewport/size/index.ts", "src/assets/javascripts/browser/viewport/_/index.ts", "src/assets/javascripts/browser/viewport/at/index.ts", "src/assets/javascripts/browser/worker/index.ts", "src/assets/javascripts/_/index.ts", "src/assets/javascripts/components/_/index.ts", "src/assets/javascripts/components/content/code/_/index.ts", "src/assets/javascripts/templates/annotation/index.tsx", "src/assets/javascripts/templates/clipboard/index.tsx", "src/assets/javascripts/templates/search/index.tsx", "src/assets/javascripts/templates/source/index.tsx", "src/assets/javascripts/templates/table/index.tsx", "src/assets/javascripts/templates/version/index.tsx", "src/assets/javascripts/components/content/annotation/_/index.ts", "src/assets/javascripts/components/content/annotation/list/index.ts", "src/assets/javascripts/components/content/code/mermaid/index.ts", "src/assets/javascripts/components/content/details/index.ts", "src/assets/javascripts/components/content/table/index.ts", "src/assets/javascripts/components/content/tabs/index.ts", "src/assets/javascripts/components/content/_/index.ts", "src/assets/javascripts/components/dialog/index.ts", "src/assets/javascripts/components/header/_/index.ts", "src/assets/javascripts/components/header/title/index.ts", "src/assets/javascripts/components/main/index.ts", "src/assets/javascripts/components/palette/index.ts", "src/assets/javascripts/integrations/clipboard/index.ts", "src/assets/javascripts/integrations/sitemap/index.ts", "src/assets/javascripts/integrations/instant/index.ts", "src/assets/javascripts/integrations/search/document/index.ts", "src/assets/javascripts/integrations/search/highlighter/index.ts", "src/assets/javascripts/integrations/search/query/transform/index.ts", "src/assets/javascripts/integrations/search/worker/message/index.ts", "src/assets/javascripts/integrations/search/worker/_/index.ts", "src/assets/javascripts/integrations/version/index.ts", "src/assets/javascripts/components/search/query/index.ts", "src/assets/javascripts/components/search/result/index.ts", "src/assets/javascripts/components/search/share/index.ts", "src/assets/javascripts/components/search/suggest/index.ts", "src/assets/javascripts/components/search/_/index.ts", "src/assets/javascripts/components/search/highlight/index.ts", "src/assets/javascripts/components/sidebar/index.ts", "src/assets/javascripts/components/source/facts/github/index.ts", "src/assets/javascripts/components/source/facts/gitlab/index.ts", "src/assets/javascripts/components/source/facts/_/index.ts", "src/assets/javascripts/components/source/_/index.ts", "src/assets/javascripts/components/tabs/index.ts", "src/assets/javascripts/components/toc/index.ts", "src/assets/javascripts/components/top/index.ts", "src/assets/javascripts/patches/indeterminate/index.ts", "src/assets/javascripts/patches/scrollfix/index.ts", "src/assets/javascripts/patches/scrolllock/index.ts", "src/assets/javascripts/polyfills/index.ts"], "sourceRoot": "../../../..", - "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "(function(global) {\r\n /**\r\n * Polyfill URLSearchParams\r\n *\r\n * Inspired from : https://github.com/WebReflection/url-search-params/blob/master/src/url-search-params.js\r\n */\r\n\r\n var checkIfIteratorIsSupported = function() {\r\n try {\r\n return !!Symbol.iterator;\r\n } catch (error) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var iteratorSupported = checkIfIteratorIsSupported();\r\n\r\n var createIterator = function(items) {\r\n var iterator = {\r\n next: function() {\r\n var value = items.shift();\r\n return { done: value === void 0, value: value };\r\n }\r\n };\r\n\r\n if (iteratorSupported) {\r\n iterator[Symbol.iterator] = function() {\r\n return iterator;\r\n };\r\n }\r\n\r\n return iterator;\r\n };\r\n\r\n /**\r\n * Search param name and values should be encoded according to https://url.spec.whatwg.org/#urlencoded-serializing\r\n * encodeURIComponent() produces the same result except encoding spaces as `%20` instead of `+`.\r\n */\r\n var serializeParam = function(value) {\r\n return encodeURIComponent(value).replace(/%20/g, '+');\r\n };\r\n\r\n var deserializeParam = function(value) {\r\n return decodeURIComponent(String(value).replace(/\\+/g, ' '));\r\n };\r\n\r\n var polyfillURLSearchParams = function() {\r\n\r\n var URLSearchParams = function(searchString) {\r\n Object.defineProperty(this, '_entries', { writable: true, value: {} });\r\n var typeofSearchString = typeof searchString;\r\n\r\n if (typeofSearchString === 'undefined') {\r\n // do nothing\r\n } else if (typeofSearchString === 'string') {\r\n if (searchString !== '') {\r\n this._fromString(searchString);\r\n }\r\n } else if (searchString instanceof URLSearchParams) {\r\n var _this = this;\r\n searchString.forEach(function(value, name) {\r\n _this.append(name, value);\r\n });\r\n } else if ((searchString !== null) && (typeofSearchString === 'object')) {\r\n if (Object.prototype.toString.call(searchString) === '[object Array]') {\r\n for (var i = 0; i < searchString.length; i++) {\r\n var entry = searchString[i];\r\n if ((Object.prototype.toString.call(entry) === '[object Array]') || (entry.length !== 2)) {\r\n this.append(entry[0], entry[1]);\r\n } else {\r\n throw new TypeError('Expected [string, any] as entry at index ' + i + ' of URLSearchParams\\'s input');\r\n }\r\n }\r\n } else {\r\n for (var key in searchString) {\r\n if (searchString.hasOwnProperty(key)) {\r\n this.append(key, searchString[key]);\r\n }\r\n }\r\n }\r\n } else {\r\n throw new TypeError('Unsupported input\\'s type for URLSearchParams');\r\n }\r\n };\r\n\r\n var proto = URLSearchParams.prototype;\r\n\r\n proto.append = function(name, value) {\r\n if (name in this._entries) {\r\n this._entries[name].push(String(value));\r\n } else {\r\n this._entries[name] = [String(value)];\r\n }\r\n };\r\n\r\n proto.delete = function(name) {\r\n delete this._entries[name];\r\n };\r\n\r\n proto.get = function(name) {\r\n return (name in this._entries) ? this._entries[name][0] : null;\r\n };\r\n\r\n proto.getAll = function(name) {\r\n return (name in this._entries) ? this._entries[name].slice(0) : [];\r\n };\r\n\r\n proto.has = function(name) {\r\n return (name in this._entries);\r\n };\r\n\r\n proto.set = function(name, value) {\r\n this._entries[name] = [String(value)];\r\n };\r\n\r\n proto.forEach = function(callback, thisArg) {\r\n var entries;\r\n for (var name in this._entries) {\r\n if (this._entries.hasOwnProperty(name)) {\r\n entries = this._entries[name];\r\n for (var i = 0; i < entries.length; i++) {\r\n callback.call(thisArg, entries[i], name, this);\r\n }\r\n }\r\n }\r\n };\r\n\r\n proto.keys = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push(name);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.values = function() {\r\n var items = [];\r\n this.forEach(function(value) {\r\n items.push(value);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.entries = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n if (iteratorSupported) {\r\n proto[Symbol.iterator] = proto.entries;\r\n }\r\n\r\n proto.toString = function() {\r\n var searchArray = [];\r\n this.forEach(function(value, name) {\r\n searchArray.push(serializeParam(name) + '=' + serializeParam(value));\r\n });\r\n return searchArray.join('&');\r\n };\r\n\r\n\r\n global.URLSearchParams = URLSearchParams;\r\n };\r\n\r\n var checkIfURLSearchParamsSupported = function() {\r\n try {\r\n var URLSearchParams = global.URLSearchParams;\r\n\r\n return (\r\n (new URLSearchParams('?a=1').toString() === 'a=1') &&\r\n (typeof URLSearchParams.prototype.set === 'function') &&\r\n (typeof URLSearchParams.prototype.entries === 'function')\r\n );\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n if (!checkIfURLSearchParamsSupported()) {\r\n polyfillURLSearchParams();\r\n }\r\n\r\n var proto = global.URLSearchParams.prototype;\r\n\r\n if (typeof proto.sort !== 'function') {\r\n proto.sort = function() {\r\n var _this = this;\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n if (!_this._entries) {\r\n _this.delete(name);\r\n }\r\n });\r\n items.sort(function(a, b) {\r\n if (a[0] < b[0]) {\r\n return -1;\r\n } else if (a[0] > b[0]) {\r\n return +1;\r\n } else {\r\n return 0;\r\n }\r\n });\r\n if (_this._entries) { // force reset because IE keeps keys index\r\n _this._entries = {};\r\n }\r\n for (var i = 0; i < items.length; i++) {\r\n this.append(items[i][0], items[i][1]);\r\n }\r\n };\r\n }\r\n\r\n if (typeof proto._fromString !== 'function') {\r\n Object.defineProperty(proto, '_fromString', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function(searchString) {\r\n if (this._entries) {\r\n this._entries = {};\r\n } else {\r\n var keys = [];\r\n this.forEach(function(value, name) {\r\n keys.push(name);\r\n });\r\n for (var i = 0; i < keys.length; i++) {\r\n this.delete(keys[i]);\r\n }\r\n }\r\n\r\n searchString = searchString.replace(/^\\?/, '');\r\n var attributes = searchString.split('&');\r\n var attribute;\r\n for (var i = 0; i < attributes.length; i++) {\r\n attribute = attributes[i].split('=');\r\n this.append(\r\n deserializeParam(attribute[0]),\r\n (attribute.length > 1) ? deserializeParam(attribute[1]) : ''\r\n );\r\n }\r\n }\r\n });\r\n }\r\n\r\n // HTMLAnchorElement\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n\r\n(function(global) {\r\n /**\r\n * Polyfill URL\r\n *\r\n * Inspired from : https://github.com/arv/DOM-URL-Polyfill/blob/master/src/url.js\r\n */\r\n\r\n var checkIfURLIsSupported = function() {\r\n try {\r\n var u = new global.URL('b', 'http://a');\r\n u.pathname = 'c d';\r\n return (u.href === 'http://a/c%20d') && u.searchParams;\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var polyfillURL = function() {\r\n var _URL = global.URL;\r\n\r\n var URL = function(url, base) {\r\n if (typeof url !== 'string') url = String(url);\r\n if (base && typeof base !== 'string') base = String(base);\r\n\r\n // Only create another document if the base is different from current location.\r\n var doc = document, baseElement;\r\n if (base && (global.location === void 0 || base !== global.location.href)) {\r\n base = base.toLowerCase();\r\n doc = document.implementation.createHTMLDocument('');\r\n baseElement = doc.createElement('base');\r\n baseElement.href = base;\r\n doc.head.appendChild(baseElement);\r\n try {\r\n if (baseElement.href.indexOf(base) !== 0) throw new Error(baseElement.href);\r\n } catch (err) {\r\n throw new Error('URL unable to set base ' + base + ' due to ' + err);\r\n }\r\n }\r\n\r\n var anchorElement = doc.createElement('a');\r\n anchorElement.href = url;\r\n if (baseElement) {\r\n doc.body.appendChild(anchorElement);\r\n anchorElement.href = anchorElement.href; // force href to refresh\r\n }\r\n\r\n var inputElement = doc.createElement('input');\r\n inputElement.type = 'url';\r\n inputElement.value = url;\r\n\r\n if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href) || (!inputElement.checkValidity() && !base)) {\r\n throw new TypeError('Invalid URL');\r\n }\r\n\r\n Object.defineProperty(this, '_anchorElement', {\r\n value: anchorElement\r\n });\r\n\r\n\r\n // create a linked searchParams which reflect its changes on URL\r\n var searchParams = new global.URLSearchParams(this.search);\r\n var enableSearchUpdate = true;\r\n var enableSearchParamsUpdate = true;\r\n var _this = this;\r\n ['append', 'delete', 'set'].forEach(function(methodName) {\r\n var method = searchParams[methodName];\r\n searchParams[methodName] = function() {\r\n method.apply(searchParams, arguments);\r\n if (enableSearchUpdate) {\r\n enableSearchParamsUpdate = false;\r\n _this.search = searchParams.toString();\r\n enableSearchParamsUpdate = true;\r\n }\r\n };\r\n });\r\n\r\n Object.defineProperty(this, 'searchParams', {\r\n value: searchParams,\r\n enumerable: true\r\n });\r\n\r\n var search = void 0;\r\n Object.defineProperty(this, '_updateSearchParams', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function() {\r\n if (this.search !== search) {\r\n search = this.search;\r\n if (enableSearchParamsUpdate) {\r\n enableSearchUpdate = false;\r\n this.searchParams._fromString(this.search);\r\n enableSearchUpdate = true;\r\n }\r\n }\r\n }\r\n });\r\n };\r\n\r\n var proto = URL.prototype;\r\n\r\n var linkURLWithAnchorAttribute = function(attributeName) {\r\n Object.defineProperty(proto, attributeName, {\r\n get: function() {\r\n return this._anchorElement[attributeName];\r\n },\r\n set: function(value) {\r\n this._anchorElement[attributeName] = value;\r\n },\r\n enumerable: true\r\n });\r\n };\r\n\r\n ['hash', 'host', 'hostname', 'port', 'protocol']\r\n .forEach(function(attributeName) {\r\n linkURLWithAnchorAttribute(attributeName);\r\n });\r\n\r\n Object.defineProperty(proto, 'search', {\r\n get: function() {\r\n return this._anchorElement['search'];\r\n },\r\n set: function(value) {\r\n this._anchorElement['search'] = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n });\r\n\r\n Object.defineProperties(proto, {\r\n\r\n 'toString': {\r\n get: function() {\r\n var _this = this;\r\n return function() {\r\n return _this.href;\r\n };\r\n }\r\n },\r\n\r\n 'href': {\r\n get: function() {\r\n return this._anchorElement.href.replace(/\\?$/, '');\r\n },\r\n set: function(value) {\r\n this._anchorElement.href = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'pathname': {\r\n get: function() {\r\n return this._anchorElement.pathname.replace(/(^\\/?)/, '/');\r\n },\r\n set: function(value) {\r\n this._anchorElement.pathname = value;\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'origin': {\r\n get: function() {\r\n // get expected port from protocol\r\n var expectedPort = { 'http:': 80, 'https:': 443, 'ftp:': 21 }[this._anchorElement.protocol];\r\n // add port to origin if, expected port is different than actual port\r\n // and it is not empty f.e http://foo:8080\r\n // 8080 != 80 && 8080 != ''\r\n var addPortToOrigin = this._anchorElement.port != expectedPort &&\r\n this._anchorElement.port !== '';\r\n\r\n return this._anchorElement.protocol +\r\n '//' +\r\n this._anchorElement.hostname +\r\n (addPortToOrigin ? (':' + this._anchorElement.port) : '');\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'password': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'username': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n });\r\n\r\n URL.createObjectURL = function(blob) {\r\n return _URL.createObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n URL.revokeObjectURL = function(url) {\r\n return _URL.revokeObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n global.URL = URL;\r\n\r\n };\r\n\r\n if (!checkIfURLIsSupported()) {\r\n polyfillURL();\r\n }\r\n\r\n if ((global.location !== void 0) && !('origin' in global.location)) {\r\n var getOrigin = function() {\r\n return global.location.protocol + '//' + global.location.hostname + (global.location.port ? (':' + global.location.port) : '');\r\n };\r\n\r\n try {\r\n Object.defineProperty(global.location, 'origin', {\r\n get: getOrigin,\r\n enumerable: true\r\n });\r\n } catch (e) {\r\n setInterval(function() {\r\n global.location.origin = getOrigin();\r\n }, 100);\r\n }\r\n }\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global global, define, System, Reflect, Promise */\r\nvar __extends;\r\nvar __assign;\r\nvar __rest;\r\nvar __decorate;\r\nvar __param;\r\nvar __metadata;\r\nvar __awaiter;\r\nvar __generator;\r\nvar __exportStar;\r\nvar __values;\r\nvar __read;\r\nvar __spread;\r\nvar __spreadArrays;\r\nvar __spreadArray;\r\nvar __await;\r\nvar __asyncGenerator;\r\nvar __asyncDelegator;\r\nvar __asyncValues;\r\nvar __makeTemplateObject;\r\nvar __importStar;\r\nvar __importDefault;\r\nvar __classPrivateFieldGet;\r\nvar __classPrivateFieldSet;\r\nvar __createBinding;\r\n(function (factory) {\r\n var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\r\n if (typeof define === \"function\" && define.amd) {\r\n define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\r\n }\r\n else if (typeof module === \"object\" && typeof module.exports === \"object\") {\r\n factory(createExporter(root, createExporter(module.exports)));\r\n }\r\n else {\r\n factory(createExporter(root));\r\n }\r\n function createExporter(exports, previous) {\r\n if (exports !== root) {\r\n if (typeof Object.create === \"function\") {\r\n Object.defineProperty(exports, \"__esModule\", { value: true });\r\n }\r\n else {\r\n exports.__esModule = true;\r\n }\r\n }\r\n return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\r\n }\r\n})\r\n(function (exporter) {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n\r\n __extends = function (d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n\r\n __assign = Object.assign || function (t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n\r\n __rest = function (s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n };\r\n\r\n __decorate = function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n __param = function (paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n };\r\n\r\n __metadata = function (metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n };\r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n __exportStar = function(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n };\r\n\r\n __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n }) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n });\r\n\r\n __values = function (o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n };\r\n\r\n __read = function (o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spread = function () {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spreadArrays = function () {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n };\r\n\r\n __spreadArray = function (to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n };\r\n\r\n __await = function (v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n };\r\n\r\n __asyncGenerator = function (thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n };\r\n\r\n __asyncDelegator = function (o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n };\r\n\r\n __asyncValues = function (o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n };\r\n\r\n __makeTemplateObject = function (cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n };\r\n\r\n var __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n }) : function(o, v) {\r\n o[\"default\"] = v;\r\n };\r\n\r\n __importStar = function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n };\r\n\r\n __importDefault = function (mod) {\r\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\r\n };\r\n\r\n __classPrivateFieldGet = function (receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n };\r\n\r\n __classPrivateFieldSet = function (receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n };\r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n exporter(\"__rest\", __rest);\r\n exporter(\"__decorate\", __decorate);\r\n exporter(\"__param\", __param);\r\n exporter(\"__metadata\", __metadata);\r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n exporter(\"__exportStar\", __exportStar);\r\n exporter(\"__createBinding\", __createBinding);\r\n exporter(\"__values\", __values);\r\n exporter(\"__read\", __read);\r\n exporter(\"__spread\", __spread);\r\n exporter(\"__spreadArrays\", __spreadArrays);\r\n exporter(\"__spreadArray\", __spreadArray);\r\n exporter(\"__await\", __await);\r\n exporter(\"__asyncGenerator\", __asyncGenerator);\r\n exporter(\"__asyncDelegator\", __asyncDelegator);\r\n exporter(\"__asyncValues\", __asyncValues);\r\n exporter(\"__makeTemplateObject\", __makeTemplateObject);\r\n exporter(\"__importStar\", __importStar);\r\n exporter(\"__importDefault\", __importDefault);\r\n exporter(\"__classPrivateFieldGet\", __classPrivateFieldGet);\r\n exporter(\"__classPrivateFieldSet\", __classPrivateFieldSet);\r\n});\r\n", "/*!\n * clipboard.js v2.0.10\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n var fakeElement = createFakeElement(target);\n options.container.appendChild(fakeElement);\n selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n document.activeElement.blur();\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "Array.prototype.flat||Object.defineProperty(Array.prototype,\"flat\",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,function(a,e){return Array.isArray(e)?a.push.apply(a,r.call(e,t-1)):a.push(e),a},[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.flatMap||Object.defineProperty(Array.prototype,\"flatMap\",{configurable:!0,value:function(r){return Array.prototype.map.apply(this,arguments).flat()},writable:!0})\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"array-flat-polyfill\"\nimport \"focus-visible\"\nimport \"unfetch/polyfill\"\nimport \"url-polyfill\"\n\nimport {\n EMPTY,\n NEVER,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getOptionalElement,\n requestJSON,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountBackToTop,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantLoading,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget()\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? __search?.index || requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up instant loading, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantLoading({ document$, location$, viewport$ })\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"[href][rel=prev]\")\n if (typeof prev !== \"undefined\")\n prev.click()\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"[href][rel=next]\")\n if (typeof next !== \"undefined\")\n next.click()\n break\n }\n })\n\n/* Set up patches */\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, { viewport$, header$, target$ })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.component$ = component$ /* Component observable */\n", "self.fetch||(self.fetch=function(e,n){return n=n||{},new Promise(function(t,s){var r=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(r.status/100|0),statusText:r.statusText,status:r.status,url:r.responseURL,text:function(){return Promise.resolve(r.responseText)},json:function(){return Promise.resolve(r.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([r.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var c in r.open(n.method||\"get\",e,!0),r.onload=function(){r.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm,function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+\",\"+t:t}),t(a())},r.onerror=s,r.withCredentials=\"include\"==n.credentials,n.headers)r.setRequestHeader(c,n.headers[c]);r.send(n.body||null)})});\n", "import tslib from '../tslib.js';\r\nconst {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n} = tslib;\r\nexport {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n};\r\n", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ReplaySubject,\n Subject,\n fromEvent\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch document\n *\n * Documents are implemented as subjects, so all downstream observables are\n * automatically updated when a new document is emitted.\n *\n * @returns Document subject\n */\nexport function watchDocument(): Subject {\n const document$ = new ReplaySubject(1)\n fromEvent(document, \"DOMContentLoaded\", { once: true })\n .subscribe(() => document$.next(document))\n\n /* Return document */\n return document$\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve all elements matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getElements(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T][]\n\nexport function getElements(\n selector: string, node?: ParentNode\n): T[]\n\nexport function getElements(\n selector: string, node: ParentNode = document\n): T[] {\n return Array.from(node.querySelectorAll(selector))\n}\n\n/**\n * Retrieve an element matching a query selector or throw a reference error\n *\n * Note that this function assumes that the element is present. If unsure if an\n * element is existent, use the `getOptionalElement` function instead.\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElement(\n selector: string, node?: ParentNode\n): T\n\nexport function getElement(\n selector: string, node: ParentNode = document\n): T {\n const el = getOptionalElement(selector, node)\n if (typeof el === \"undefined\")\n throw new ReferenceError(\n `Missing element: expected \"${selector}\" to be present`\n )\n\n /* Return element */\n return el\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Retrieve an optional element matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element or nothing\n */\nexport function getOptionalElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T] | undefined\n\nexport function getOptionalElement(\n selector: string, node?: ParentNode\n): T | undefined\n\nexport function getOptionalElement(\n selector: string, node: ParentNode = document\n): T | undefined {\n return node.querySelector(selector) || undefined\n}\n\n/**\n * Retrieve the currently active element\n *\n * @returns Element or nothing\n */\nexport function getActiveElement(): HTMLElement | undefined {\n return document.activeElement instanceof HTMLElement\n ? document.activeElement || undefined\n : undefined\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n debounceTime,\n distinctUntilChanged,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element focus\n *\n * Previously, this function used `focus` and `blur` events to determine whether\n * an element is focused, but this doesn't work if there are focusable elements\n * within the elements itself. A better solutions are `focusin` and `focusout`\n * events, which bubble up the tree and allow for more fine-grained control.\n *\n * `debounceTime` is necessary, because when a focus change happens inside an\n * element, the observable would first emit `false` and then `true` again.\n *\n * @param el - Element\n *\n * @returns Element focus observable\n */\nexport function watchElementFocus(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(document.body, \"focusin\"),\n fromEvent(document.body, \"focusout\")\n )\n .pipe(\n debounceTime(1),\n map(() => {\n const active = getActiveElement()\n return typeof active !== \"undefined\"\n ? el.contains(active)\n : false\n }),\n startWith(el === getActiveElement()),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element offset\n *\n * @param el - Element\n *\n * @returns Element offset\n */\nexport function getElementOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.offsetLeft,\n y: el.offsetTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element offset\n *\n * @param el - Element\n *\n * @returns Element offset observable\n */\nexport function watchElementOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(window, \"load\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementOffset(el)),\n startWith(getElementOffset(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { ElementOffset } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content offset (= scroll offset)\n *\n * @param el - Element\n *\n * @returns Element content offset\n */\nexport function getElementContentOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.scrollLeft,\n y: el.scrollTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element content offset\n *\n * @param el - Element\n *\n * @returns Element content offset observable\n */\nexport function watchElementContentOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(el, \"scroll\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementContentOffset(el)),\n startWith(getElementContentOffset(el))\n )\n}\n", "/**\r\n * A collection of shims that provide minimal functionality of the ES6 collections.\r\n *\r\n * These implementations are not meant to be used outside of the ResizeObserver\r\n * modules as they cover only a limited range of use cases.\r\n */\r\n/* eslint-disable require-jsdoc, valid-jsdoc */\r\nvar MapShim = (function () {\r\n if (typeof Map !== 'undefined') {\r\n return Map;\r\n }\r\n /**\r\n * Returns index in provided array that matches the specified key.\r\n *\r\n * @param {Array} arr\r\n * @param {*} key\r\n * @returns {number}\r\n */\r\n function getIndex(arr, key) {\r\n var result = -1;\r\n arr.some(function (entry, index) {\r\n if (entry[0] === key) {\r\n result = index;\r\n return true;\r\n }\r\n return false;\r\n });\r\n return result;\r\n }\r\n return /** @class */ (function () {\r\n function class_1() {\r\n this.__entries__ = [];\r\n }\r\n Object.defineProperty(class_1.prototype, \"size\", {\r\n /**\r\n * @returns {boolean}\r\n */\r\n get: function () {\r\n return this.__entries__.length;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {*} key\r\n * @returns {*}\r\n */\r\n class_1.prototype.get = function (key) {\r\n var index = getIndex(this.__entries__, key);\r\n var entry = this.__entries__[index];\r\n return entry && entry[1];\r\n };\r\n /**\r\n * @param {*} key\r\n * @param {*} value\r\n * @returns {void}\r\n */\r\n class_1.prototype.set = function (key, value) {\r\n var index = getIndex(this.__entries__, key);\r\n if (~index) {\r\n this.__entries__[index][1] = value;\r\n }\r\n else {\r\n this.__entries__.push([key, value]);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.delete = function (key) {\r\n var entries = this.__entries__;\r\n var index = getIndex(entries, key);\r\n if (~index) {\r\n entries.splice(index, 1);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.has = function (key) {\r\n return !!~getIndex(this.__entries__, key);\r\n };\r\n /**\r\n * @returns {void}\r\n */\r\n class_1.prototype.clear = function () {\r\n this.__entries__.splice(0);\r\n };\r\n /**\r\n * @param {Function} callback\r\n * @param {*} [ctx=null]\r\n * @returns {void}\r\n */\r\n class_1.prototype.forEach = function (callback, ctx) {\r\n if (ctx === void 0) { ctx = null; }\r\n for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {\r\n var entry = _a[_i];\r\n callback.call(ctx, entry[1], entry[0]);\r\n }\r\n };\r\n return class_1;\r\n }());\r\n})();\n\n/**\r\n * Detects whether window and document objects are available in current environment.\r\n */\r\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;\n\n// Returns global object of a current environment.\r\nvar global$1 = (function () {\r\n if (typeof global !== 'undefined' && global.Math === Math) {\r\n return global;\r\n }\r\n if (typeof self !== 'undefined' && self.Math === Math) {\r\n return self;\r\n }\r\n if (typeof window !== 'undefined' && window.Math === Math) {\r\n return window;\r\n }\r\n // eslint-disable-next-line no-new-func\r\n return Function('return this')();\r\n})();\n\n/**\r\n * A shim for the requestAnimationFrame which falls back to the setTimeout if\r\n * first one is not supported.\r\n *\r\n * @returns {number} Requests' identifier.\r\n */\r\nvar requestAnimationFrame$1 = (function () {\r\n if (typeof requestAnimationFrame === 'function') {\r\n // It's required to use a bounded function because IE sometimes throws\r\n // an \"Invalid calling object\" error if rAF is invoked without the global\r\n // object on the left hand side.\r\n return requestAnimationFrame.bind(global$1);\r\n }\r\n return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };\r\n})();\n\n// Defines minimum timeout before adding a trailing call.\r\nvar trailingTimeout = 2;\r\n/**\r\n * Creates a wrapper function which ensures that provided callback will be\r\n * invoked only once during the specified delay period.\r\n *\r\n * @param {Function} callback - Function to be invoked after the delay period.\r\n * @param {number} delay - Delay after which to invoke callback.\r\n * @returns {Function}\r\n */\r\nfunction throttle (callback, delay) {\r\n var leadingCall = false, trailingCall = false, lastCallTime = 0;\r\n /**\r\n * Invokes the original callback function and schedules new invocation if\r\n * the \"proxy\" was called during current request.\r\n *\r\n * @returns {void}\r\n */\r\n function resolvePending() {\r\n if (leadingCall) {\r\n leadingCall = false;\r\n callback();\r\n }\r\n if (trailingCall) {\r\n proxy();\r\n }\r\n }\r\n /**\r\n * Callback invoked after the specified delay. It will further postpone\r\n * invocation of the original function delegating it to the\r\n * requestAnimationFrame.\r\n *\r\n * @returns {void}\r\n */\r\n function timeoutCallback() {\r\n requestAnimationFrame$1(resolvePending);\r\n }\r\n /**\r\n * Schedules invocation of the original function.\r\n *\r\n * @returns {void}\r\n */\r\n function proxy() {\r\n var timeStamp = Date.now();\r\n if (leadingCall) {\r\n // Reject immediately following calls.\r\n if (timeStamp - lastCallTime < trailingTimeout) {\r\n return;\r\n }\r\n // Schedule new call to be in invoked when the pending one is resolved.\r\n // This is important for \"transitions\" which never actually start\r\n // immediately so there is a chance that we might miss one if change\r\n // happens amids the pending invocation.\r\n trailingCall = true;\r\n }\r\n else {\r\n leadingCall = true;\r\n trailingCall = false;\r\n setTimeout(timeoutCallback, delay);\r\n }\r\n lastCallTime = timeStamp;\r\n }\r\n return proxy;\r\n}\n\n// Minimum delay before invoking the update of observers.\r\nvar REFRESH_DELAY = 20;\r\n// A list of substrings of CSS properties used to find transition events that\r\n// might affect dimensions of observed elements.\r\nvar transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];\r\n// Check if MutationObserver is available.\r\nvar mutationObserverSupported = typeof MutationObserver !== 'undefined';\r\n/**\r\n * Singleton controller class which handles updates of ResizeObserver instances.\r\n */\r\nvar ResizeObserverController = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserverController.\r\n *\r\n * @private\r\n */\r\n function ResizeObserverController() {\r\n /**\r\n * Indicates whether DOM listeners have been added.\r\n *\r\n * @private {boolean}\r\n */\r\n this.connected_ = false;\r\n /**\r\n * Tells that controller has subscribed for Mutation Events.\r\n *\r\n * @private {boolean}\r\n */\r\n this.mutationEventsAdded_ = false;\r\n /**\r\n * Keeps reference to the instance of MutationObserver.\r\n *\r\n * @private {MutationObserver}\r\n */\r\n this.mutationsObserver_ = null;\r\n /**\r\n * A list of connected observers.\r\n *\r\n * @private {Array}\r\n */\r\n this.observers_ = [];\r\n this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);\r\n this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);\r\n }\r\n /**\r\n * Adds observer to observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be added.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.addObserver = function (observer) {\r\n if (!~this.observers_.indexOf(observer)) {\r\n this.observers_.push(observer);\r\n }\r\n // Add listeners if they haven't been added yet.\r\n if (!this.connected_) {\r\n this.connect_();\r\n }\r\n };\r\n /**\r\n * Removes observer from observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be removed.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.removeObserver = function (observer) {\r\n var observers = this.observers_;\r\n var index = observers.indexOf(observer);\r\n // Remove observer if it's present in registry.\r\n if (~index) {\r\n observers.splice(index, 1);\r\n }\r\n // Remove listeners if controller has no connected observers.\r\n if (!observers.length && this.connected_) {\r\n this.disconnect_();\r\n }\r\n };\r\n /**\r\n * Invokes the update of observers. It will continue running updates insofar\r\n * it detects changes.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.refresh = function () {\r\n var changesDetected = this.updateObservers_();\r\n // Continue running updates if changes have been detected as there might\r\n // be future ones caused by CSS transitions.\r\n if (changesDetected) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Updates every observer from observers list and notifies them of queued\r\n * entries.\r\n *\r\n * @private\r\n * @returns {boolean} Returns \"true\" if any observer has detected changes in\r\n * dimensions of it's elements.\r\n */\r\n ResizeObserverController.prototype.updateObservers_ = function () {\r\n // Collect observers that have active observations.\r\n var activeObservers = this.observers_.filter(function (observer) {\r\n return observer.gatherActive(), observer.hasActive();\r\n });\r\n // Deliver notifications in a separate cycle in order to avoid any\r\n // collisions between observers, e.g. when multiple instances of\r\n // ResizeObserver are tracking the same element and the callback of one\r\n // of them changes content dimensions of the observed target. Sometimes\r\n // this may result in notifications being blocked for the rest of observers.\r\n activeObservers.forEach(function (observer) { return observer.broadcastActive(); });\r\n return activeObservers.length > 0;\r\n };\r\n /**\r\n * Initializes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.connect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already added.\r\n if (!isBrowser || this.connected_) {\r\n return;\r\n }\r\n // Subscription to the \"Transitionend\" event is used as a workaround for\r\n // delayed transitions. This way it's possible to capture at least the\r\n // final state of an element.\r\n document.addEventListener('transitionend', this.onTransitionEnd_);\r\n window.addEventListener('resize', this.refresh);\r\n if (mutationObserverSupported) {\r\n this.mutationsObserver_ = new MutationObserver(this.refresh);\r\n this.mutationsObserver_.observe(document, {\r\n attributes: true,\r\n childList: true,\r\n characterData: true,\r\n subtree: true\r\n });\r\n }\r\n else {\r\n document.addEventListener('DOMSubtreeModified', this.refresh);\r\n this.mutationEventsAdded_ = true;\r\n }\r\n this.connected_ = true;\r\n };\r\n /**\r\n * Removes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.disconnect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already removed.\r\n if (!isBrowser || !this.connected_) {\r\n return;\r\n }\r\n document.removeEventListener('transitionend', this.onTransitionEnd_);\r\n window.removeEventListener('resize', this.refresh);\r\n if (this.mutationsObserver_) {\r\n this.mutationsObserver_.disconnect();\r\n }\r\n if (this.mutationEventsAdded_) {\r\n document.removeEventListener('DOMSubtreeModified', this.refresh);\r\n }\r\n this.mutationsObserver_ = null;\r\n this.mutationEventsAdded_ = false;\r\n this.connected_ = false;\r\n };\r\n /**\r\n * \"Transitionend\" event handler.\r\n *\r\n * @private\r\n * @param {TransitionEvent} event\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {\r\n var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;\r\n // Detect whether transition may affect dimensions of an element.\r\n var isReflowProperty = transitionKeys.some(function (key) {\r\n return !!~propertyName.indexOf(key);\r\n });\r\n if (isReflowProperty) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Returns instance of the ResizeObserverController.\r\n *\r\n * @returns {ResizeObserverController}\r\n */\r\n ResizeObserverController.getInstance = function () {\r\n if (!this.instance_) {\r\n this.instance_ = new ResizeObserverController();\r\n }\r\n return this.instance_;\r\n };\r\n /**\r\n * Holds reference to the controller's instance.\r\n *\r\n * @private {ResizeObserverController}\r\n */\r\n ResizeObserverController.instance_ = null;\r\n return ResizeObserverController;\r\n}());\n\n/**\r\n * Defines non-writable/enumerable properties of the provided target object.\r\n *\r\n * @param {Object} target - Object for which to define properties.\r\n * @param {Object} props - Properties to be defined.\r\n * @returns {Object} Target object.\r\n */\r\nvar defineConfigurable = (function (target, props) {\r\n for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {\r\n var key = _a[_i];\r\n Object.defineProperty(target, key, {\r\n value: props[key],\r\n enumerable: false,\r\n writable: false,\r\n configurable: true\r\n });\r\n }\r\n return target;\r\n});\n\n/**\r\n * Returns the global object associated with provided element.\r\n *\r\n * @param {Object} target\r\n * @returns {Object}\r\n */\r\nvar getWindowOf = (function (target) {\r\n // Assume that the element is an instance of Node, which means that it\r\n // has the \"ownerDocument\" property from which we can retrieve a\r\n // corresponding global object.\r\n var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;\r\n // Return the local global object if it's not possible extract one from\r\n // provided element.\r\n return ownerGlobal || global$1;\r\n});\n\n// Placeholder of an empty content rectangle.\r\nvar emptyRect = createRectInit(0, 0, 0, 0);\r\n/**\r\n * Converts provided string to a number.\r\n *\r\n * @param {number|string} value\r\n * @returns {number}\r\n */\r\nfunction toFloat(value) {\r\n return parseFloat(value) || 0;\r\n}\r\n/**\r\n * Extracts borders size from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @param {...string} positions - Borders positions (top, right, ...)\r\n * @returns {number}\r\n */\r\nfunction getBordersSize(styles) {\r\n var positions = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n positions[_i - 1] = arguments[_i];\r\n }\r\n return positions.reduce(function (size, position) {\r\n var value = styles['border-' + position + '-width'];\r\n return size + toFloat(value);\r\n }, 0);\r\n}\r\n/**\r\n * Extracts paddings sizes from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @returns {Object} Paddings box.\r\n */\r\nfunction getPaddings(styles) {\r\n var positions = ['top', 'right', 'bottom', 'left'];\r\n var paddings = {};\r\n for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {\r\n var position = positions_1[_i];\r\n var value = styles['padding-' + position];\r\n paddings[position] = toFloat(value);\r\n }\r\n return paddings;\r\n}\r\n/**\r\n * Calculates content rectangle of provided SVG element.\r\n *\r\n * @param {SVGGraphicsElement} target - Element content rectangle of which needs\r\n * to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getSVGContentRect(target) {\r\n var bbox = target.getBBox();\r\n return createRectInit(0, 0, bbox.width, bbox.height);\r\n}\r\n/**\r\n * Calculates content rectangle of provided HTMLElement.\r\n *\r\n * @param {HTMLElement} target - Element for which to calculate the content rectangle.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getHTMLElementContentRect(target) {\r\n // Client width & height properties can't be\r\n // used exclusively as they provide rounded values.\r\n var clientWidth = target.clientWidth, clientHeight = target.clientHeight;\r\n // By this condition we can catch all non-replaced inline, hidden and\r\n // detached elements. Though elements with width & height properties less\r\n // than 0.5 will be discarded as well.\r\n //\r\n // Without it we would need to implement separate methods for each of\r\n // those cases and it's not possible to perform a precise and performance\r\n // effective test for hidden elements. E.g. even jQuery's ':visible' filter\r\n // gives wrong results for elements with width & height less than 0.5.\r\n if (!clientWidth && !clientHeight) {\r\n return emptyRect;\r\n }\r\n var styles = getWindowOf(target).getComputedStyle(target);\r\n var paddings = getPaddings(styles);\r\n var horizPad = paddings.left + paddings.right;\r\n var vertPad = paddings.top + paddings.bottom;\r\n // Computed styles of width & height are being used because they are the\r\n // only dimensions available to JS that contain non-rounded values. It could\r\n // be possible to utilize the getBoundingClientRect if only it's data wasn't\r\n // affected by CSS transformations let alone paddings, borders and scroll bars.\r\n var width = toFloat(styles.width), height = toFloat(styles.height);\r\n // Width & height include paddings and borders when the 'border-box' box\r\n // model is applied (except for IE).\r\n if (styles.boxSizing === 'border-box') {\r\n // Following conditions are required to handle Internet Explorer which\r\n // doesn't include paddings and borders to computed CSS dimensions.\r\n //\r\n // We can say that if CSS dimensions + paddings are equal to the \"client\"\r\n // properties then it's either IE, and thus we don't need to subtract\r\n // anything, or an element merely doesn't have paddings/borders styles.\r\n if (Math.round(width + horizPad) !== clientWidth) {\r\n width -= getBordersSize(styles, 'left', 'right') + horizPad;\r\n }\r\n if (Math.round(height + vertPad) !== clientHeight) {\r\n height -= getBordersSize(styles, 'top', 'bottom') + vertPad;\r\n }\r\n }\r\n // Following steps can't be applied to the document's root element as its\r\n // client[Width/Height] properties represent viewport area of the window.\r\n // Besides, it's as well not necessary as the itself neither has\r\n // rendered scroll bars nor it can be clipped.\r\n if (!isDocumentElement(target)) {\r\n // In some browsers (only in Firefox, actually) CSS width & height\r\n // include scroll bars size which can be removed at this step as scroll\r\n // bars are the only difference between rounded dimensions + paddings\r\n // and \"client\" properties, though that is not always true in Chrome.\r\n var vertScrollbar = Math.round(width + horizPad) - clientWidth;\r\n var horizScrollbar = Math.round(height + vertPad) - clientHeight;\r\n // Chrome has a rather weird rounding of \"client\" properties.\r\n // E.g. for an element with content width of 314.2px it sometimes gives\r\n // the client width of 315px and for the width of 314.7px it may give\r\n // 314px. And it doesn't happen all the time. So just ignore this delta\r\n // as a non-relevant.\r\n if (Math.abs(vertScrollbar) !== 1) {\r\n width -= vertScrollbar;\r\n }\r\n if (Math.abs(horizScrollbar) !== 1) {\r\n height -= horizScrollbar;\r\n }\r\n }\r\n return createRectInit(paddings.left, paddings.top, width, height);\r\n}\r\n/**\r\n * Checks whether provided element is an instance of the SVGGraphicsElement.\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nvar isSVGGraphicsElement = (function () {\r\n // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement\r\n // interface.\r\n if (typeof SVGGraphicsElement !== 'undefined') {\r\n return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };\r\n }\r\n // If it's so, then check that element is at least an instance of the\r\n // SVGElement and that it has the \"getBBox\" method.\r\n // eslint-disable-next-line no-extra-parens\r\n return function (target) { return (target instanceof getWindowOf(target).SVGElement &&\r\n typeof target.getBBox === 'function'); };\r\n})();\r\n/**\r\n * Checks whether provided element is a document element ().\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nfunction isDocumentElement(target) {\r\n return target === getWindowOf(target).document.documentElement;\r\n}\r\n/**\r\n * Calculates an appropriate content rectangle for provided html or svg element.\r\n *\r\n * @param {Element} target - Element content rectangle of which needs to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getContentRect(target) {\r\n if (!isBrowser) {\r\n return emptyRect;\r\n }\r\n if (isSVGGraphicsElement(target)) {\r\n return getSVGContentRect(target);\r\n }\r\n return getHTMLElementContentRect(target);\r\n}\r\n/**\r\n * Creates rectangle with an interface of the DOMRectReadOnly.\r\n * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly\r\n *\r\n * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.\r\n * @returns {DOMRectReadOnly}\r\n */\r\nfunction createReadOnlyRect(_a) {\r\n var x = _a.x, y = _a.y, width = _a.width, height = _a.height;\r\n // If DOMRectReadOnly is available use it as a prototype for the rectangle.\r\n var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;\r\n var rect = Object.create(Constr.prototype);\r\n // Rectangle's properties are not writable and non-enumerable.\r\n defineConfigurable(rect, {\r\n x: x, y: y, width: width, height: height,\r\n top: y,\r\n right: x + width,\r\n bottom: height + y,\r\n left: x\r\n });\r\n return rect;\r\n}\r\n/**\r\n * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.\r\n * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit\r\n *\r\n * @param {number} x - X coordinate.\r\n * @param {number} y - Y coordinate.\r\n * @param {number} width - Rectangle's width.\r\n * @param {number} height - Rectangle's height.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction createRectInit(x, y, width, height) {\r\n return { x: x, y: y, width: width, height: height };\r\n}\n\n/**\r\n * Class that is responsible for computations of the content rectangle of\r\n * provided DOM element and for keeping track of it's changes.\r\n */\r\nvar ResizeObservation = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObservation.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n */\r\n function ResizeObservation(target) {\r\n /**\r\n * Broadcasted width of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastWidth = 0;\r\n /**\r\n * Broadcasted height of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastHeight = 0;\r\n /**\r\n * Reference to the last observed content rectangle.\r\n *\r\n * @private {DOMRectInit}\r\n */\r\n this.contentRect_ = createRectInit(0, 0, 0, 0);\r\n this.target = target;\r\n }\r\n /**\r\n * Updates content rectangle and tells whether it's width or height properties\r\n * have changed since the last broadcast.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObservation.prototype.isActive = function () {\r\n var rect = getContentRect(this.target);\r\n this.contentRect_ = rect;\r\n return (rect.width !== this.broadcastWidth ||\r\n rect.height !== this.broadcastHeight);\r\n };\r\n /**\r\n * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data\r\n * from the corresponding properties of the last observed content rectangle.\r\n *\r\n * @returns {DOMRectInit} Last observed content rectangle.\r\n */\r\n ResizeObservation.prototype.broadcastRect = function () {\r\n var rect = this.contentRect_;\r\n this.broadcastWidth = rect.width;\r\n this.broadcastHeight = rect.height;\r\n return rect;\r\n };\r\n return ResizeObservation;\r\n}());\n\nvar ResizeObserverEntry = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObserverEntry.\r\n *\r\n * @param {Element} target - Element that is being observed.\r\n * @param {DOMRectInit} rectInit - Data of the element's content rectangle.\r\n */\r\n function ResizeObserverEntry(target, rectInit) {\r\n var contentRect = createReadOnlyRect(rectInit);\r\n // According to the specification following properties are not writable\r\n // and are also not enumerable in the native implementation.\r\n //\r\n // Property accessors are not being used as they'd require to define a\r\n // private WeakMap storage which may cause memory leaks in browsers that\r\n // don't support this type of collections.\r\n defineConfigurable(this, { target: target, contentRect: contentRect });\r\n }\r\n return ResizeObserverEntry;\r\n}());\n\nvar ResizeObserverSPI = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback function that is invoked\r\n * when one of the observed elements changes it's content dimensions.\r\n * @param {ResizeObserverController} controller - Controller instance which\r\n * is responsible for the updates of observer.\r\n * @param {ResizeObserver} callbackCtx - Reference to the public\r\n * ResizeObserver instance which will be passed to callback function.\r\n */\r\n function ResizeObserverSPI(callback, controller, callbackCtx) {\r\n /**\r\n * Collection of resize observations that have detected changes in dimensions\r\n * of elements.\r\n *\r\n * @private {Array}\r\n */\r\n this.activeObservations_ = [];\r\n /**\r\n * Registry of the ResizeObservation instances.\r\n *\r\n * @private {Map}\r\n */\r\n this.observations_ = new MapShim();\r\n if (typeof callback !== 'function') {\r\n throw new TypeError('The callback provided as parameter 1 is not a function.');\r\n }\r\n this.callback_ = callback;\r\n this.controller_ = controller;\r\n this.callbackCtx_ = callbackCtx;\r\n }\r\n /**\r\n * Starts observing provided element.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.observe = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is already being observed.\r\n if (observations.has(target)) {\r\n return;\r\n }\r\n observations.set(target, new ResizeObservation(target));\r\n this.controller_.addObserver(this);\r\n // Force the update of observations.\r\n this.controller_.refresh();\r\n };\r\n /**\r\n * Stops observing provided element.\r\n *\r\n * @param {Element} target - Element to stop observing.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.unobserve = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is not being observed.\r\n if (!observations.has(target)) {\r\n return;\r\n }\r\n observations.delete(target);\r\n if (!observations.size) {\r\n this.controller_.removeObserver(this);\r\n }\r\n };\r\n /**\r\n * Stops observing all elements.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.disconnect = function () {\r\n this.clearActive();\r\n this.observations_.clear();\r\n this.controller_.removeObserver(this);\r\n };\r\n /**\r\n * Collects observation instances the associated element of which has changed\r\n * it's content rectangle.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.gatherActive = function () {\r\n var _this = this;\r\n this.clearActive();\r\n this.observations_.forEach(function (observation) {\r\n if (observation.isActive()) {\r\n _this.activeObservations_.push(observation);\r\n }\r\n });\r\n };\r\n /**\r\n * Invokes initial callback function with a list of ResizeObserverEntry\r\n * instances collected from active resize observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.broadcastActive = function () {\r\n // Do nothing if observer doesn't have active observations.\r\n if (!this.hasActive()) {\r\n return;\r\n }\r\n var ctx = this.callbackCtx_;\r\n // Create ResizeObserverEntry instance for every active observation.\r\n var entries = this.activeObservations_.map(function (observation) {\r\n return new ResizeObserverEntry(observation.target, observation.broadcastRect());\r\n });\r\n this.callback_.call(ctx, entries, ctx);\r\n this.clearActive();\r\n };\r\n /**\r\n * Clears the collection of active observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.clearActive = function () {\r\n this.activeObservations_.splice(0);\r\n };\r\n /**\r\n * Tells whether observer has active observations.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObserverSPI.prototype.hasActive = function () {\r\n return this.activeObservations_.length > 0;\r\n };\r\n return ResizeObserverSPI;\r\n}());\n\n// Registry of internal observers. If WeakMap is not available use current shim\r\n// for the Map collection as it has all required methods and because WeakMap\r\n// can't be fully polyfilled anyway.\r\nvar observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();\r\n/**\r\n * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation\r\n * exposing only those methods and properties that are defined in the spec.\r\n */\r\nvar ResizeObserver = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback that is invoked when\r\n * dimensions of the observed elements change.\r\n */\r\n function ResizeObserver(callback) {\r\n if (!(this instanceof ResizeObserver)) {\r\n throw new TypeError('Cannot call a class as a function.');\r\n }\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n var controller = ResizeObserverController.getInstance();\r\n var observer = new ResizeObserverSPI(callback, controller, this);\r\n observers.set(this, observer);\r\n }\r\n return ResizeObserver;\r\n}());\r\n// Expose public methods of ResizeObserver.\r\n[\r\n 'observe',\r\n 'unobserve',\r\n 'disconnect'\r\n].forEach(function (method) {\r\n ResizeObserver.prototype[method] = function () {\r\n var _a;\r\n return (_a = observers.get(this))[method].apply(_a, arguments);\r\n };\r\n});\n\nvar index = (function () {\r\n // Export existing implementation if available.\r\n if (typeof global$1.ResizeObserver !== 'undefined') {\r\n return global$1.ResizeObserver;\r\n }\r\n return ResizeObserver;\r\n})();\n\nexport default index;\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ResizeObserver from \"resize-observer-polyfill\"\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n startWith,\n switchMap,\n tap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementSize {\n width: number /* Element width */\n height: number /* Element height */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Resize observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Resize observer observable\n *\n * This observable will create a `ResizeObserver` on the first subscription\n * and will automatically terminate it when there are no more subscribers.\n * It's quite important to centralize observation in a single `ResizeObserver`,\n * as the performance difference can be quite dramatic, as the link shows.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new ResizeObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element size\n *\n * @param el - Element\n *\n * @returns Element size\n */\nexport function getElementSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.offsetWidth,\n height: el.offsetHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element size\n *\n * This function returns an observable that subscribes to a single internal\n * instance of `ResizeObserver` upon subscription, and emit resize events until\n * termination. Note that this function should not be called with the same\n * element twice, as the first unsubscription will terminate observation.\n *\n * Sadly, we can't use the `DOMRect` objects returned by the observer, because\n * we need the emitted values to be consistent with `getElementSize`, which will\n * return the used values (rounded) and not actual values (unrounded). Thus, we\n * use the `offset*` properties. See the linked GitHub issue.\n *\n * @see https://bit.ly/3m0k3he - GitHub issue\n *\n * @param el - Element\n *\n * @returns Element size observable\n */\nexport function watchElementSize(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(() => getElementSize(el))\n )\n ),\n startWith(getElementSize(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ElementSize } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content size (= scroll width and height)\n *\n * @param el - Element\n *\n * @returns Element content size\n */\nexport function getElementContentSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.scrollWidth,\n height: el.scrollHeight\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport {\n getElementContentSize,\n getElementSize,\n watchElementContentOffset\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Intersection observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Intersection observer observable\n *\n * This observable will create an `IntersectionObserver` on first subscription\n * and will automatically terminate it when there are no more subscribers.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new IntersectionObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n }, {\n threshold: 0\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element visibility\n *\n * @param el - Element\n *\n * @returns Element visibility observable\n */\nexport function watchElementVisibility(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(({ isIntersecting }) => isIntersecting)\n )\n )\n )\n}\n\n/**\n * Watch element boundary\n *\n * This function returns an observable which emits whether the bottom content\n * boundary (= scroll offset) of an element is within a certain threshold.\n *\n * @param el - Element\n * @param threshold - Threshold\n *\n * @returns Element boundary observable\n */\nexport function watchElementBoundary(\n el: HTMLElement, threshold = 16\n): Observable {\n return watchElementContentOffset(el)\n .pipe(\n map(({ y }) => {\n const visible = getElementSize(el)\n const content = getElementContentSize(el)\n return y >= (\n content.height - visible.height - threshold\n )\n }),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getElement } from \"../element\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle\n */\nexport type Toggle =\n | \"drawer\" /* Toggle for drawer */\n | \"search\" /* Toggle for search */\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle map\n */\nconst toggles: Record = {\n drawer: getElement(\"[data-md-toggle=drawer]\"),\n search: getElement(\"[data-md-toggle=search]\")\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the value of a toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value\n */\nexport function getToggle(name: Toggle): boolean {\n return toggles[name].checked\n}\n\n/**\n * Set toggle\n *\n * Simulating a click event seems to be the most cross-browser compatible way\n * of changing the value while also emitting a `change` event. Before, Material\n * used `CustomEvent` to programmatically change the value of a toggle, but this\n * is a much simpler and cleaner solution which doesn't require a polyfill.\n *\n * @param name - Toggle\n * @param value - Toggle value\n */\nexport function setToggle(name: Toggle, value: boolean): void {\n if (toggles[name].checked !== value)\n toggles[name].click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value observable\n */\nexport function watchToggle(name: Toggle): Observable {\n const el = toggles[name]\n return fromEvent(el, \"change\")\n .pipe(\n map(() => el.checked),\n startWith(el.checked)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n share\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../element\"\nimport { getToggle } from \"../toggle\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Keyboard mode\n */\nexport type KeyboardMode =\n | \"global\" /* Global */\n | \"search\" /* Search is open */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Keyboard\n */\nexport interface Keyboard {\n mode: KeyboardMode /* Keyboard mode */\n type: string /* Key type */\n claim(): void /* Key claim */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether an element may receive keyboard input\n *\n * @param el - Element\n * @param type - Key type\n *\n * @returns Test result\n */\nfunction isSusceptibleToKeyboard(\n el: HTMLElement, type: string\n): boolean {\n switch (el.constructor) {\n\n /* Input elements */\n case HTMLInputElement:\n /* @ts-expect-error - omit unnecessary type cast */\n if (el.type === \"radio\")\n return /^Arrow/.test(type)\n else\n return true\n\n /* Select element and textarea */\n case HTMLSelectElement:\n case HTMLTextAreaElement:\n return true\n\n /* Everything else */\n default:\n return el.isContentEditable\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch keyboard\n *\n * @returns Keyboard observable\n */\nexport function watchKeyboard(): Observable {\n return fromEvent(window, \"keydown\")\n .pipe(\n filter(ev => !(ev.metaKey || ev.ctrlKey)),\n map(ev => ({\n mode: getToggle(\"search\") ? \"search\" : \"global\",\n type: ev.key,\n claim() {\n ev.preventDefault()\n ev.stopPropagation()\n }\n } as Keyboard)),\n filter(({ mode, type }) => {\n if (mode === \"global\") {\n const active = getActiveElement()\n if (typeof active !== \"undefined\")\n return !isSusceptibleToKeyboard(active, type)\n }\n return true\n }),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Subject } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location\n *\n * This function returns a `URL` object (and not `Location`) to normalize the\n * typings across the application. Furthermore, locations need to be tracked\n * without setting them and `Location` is a singleton which represents the\n * current location.\n *\n * @returns URL\n */\nexport function getLocation(): URL {\n return new URL(location.href)\n}\n\n/**\n * Set location\n *\n * @param url - URL to change to\n */\nexport function setLocation(url: URL): void {\n location.href = url.href\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location\n *\n * @returns Location subject\n */\nexport function watchLocation(): Subject {\n return new Subject()\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { JSX as JSXInternal } from \"preact\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * HTML attributes\n */\ntype Attributes =\n & JSXInternal.HTMLAttributes\n & JSXInternal.SVGAttributes\n & Record\n\n/**\n * Child element\n */\ntype Child =\n | HTMLElement\n | Text\n | string\n | number\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Append a child node to an element\n *\n * @param el - Element\n * @param child - Child node(s)\n */\nfunction appendChild(el: HTMLElement, child: Child | Child[]): void {\n\n /* Handle primitive types (including raw HTML) */\n if (typeof child === \"string\" || typeof child === \"number\") {\n el.innerHTML += child.toString()\n\n /* Handle nodes */\n } else if (child instanceof Node) {\n el.appendChild(child)\n\n /* Handle nested children */\n } else if (Array.isArray(child)) {\n for (const node of child)\n appendChild(el, node)\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * JSX factory\n *\n * @template T - Element type\n *\n * @param tag - HTML tag\n * @param attributes - HTML attributes\n * @param children - Child elements\n *\n * @returns Element\n */\nexport function h(\n tag: T, attributes?: Attributes | null, ...children: Child[]\n): HTMLElementTagNameMap[T]\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T {\n const el = document.createElement(tag)\n\n /* Set attributes, if any */\n if (attributes)\n for (const attr of Object.keys(attributes))\n if (typeof attributes[attr] !== \"boolean\")\n el.setAttribute(attr, attributes[attr])\n else if (attributes[attr])\n el.setAttribute(attr, \"\")\n\n /* Append child nodes */\n for (const child of children)\n appendChild(el, child)\n\n /* Return element */\n return el as T\n}\n\n/* ----------------------------------------------------------------------------\n * Namespace\n * ------------------------------------------------------------------------- */\n\nexport declare namespace h {\n namespace JSX {\n type Element = HTMLElement\n type IntrinsicElements = JSXInternal.IntrinsicElements\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Truncate a string after the given number of characters\n *\n * This is not a very reasonable approach, since the summaries kind of suck.\n * It would be better to create something more intelligent, highlighting the\n * search occurrences and making a better summary out of it, but this note was\n * written three years ago, so who knows if we'll ever fix it.\n *\n * @param value - Value to be truncated\n * @param n - Number of characters\n *\n * @returns Truncated value\n */\nexport function truncate(value: string, n: number): string {\n let i = n\n if (value.length > i) {\n while (value[i] !== \" \" && --i > 0) { /* keep eating */ }\n return `${value.substring(0, i)}...`\n }\n return value\n}\n\n/**\n * Round a number for display with repository facts\n *\n * This is a reverse-engineered version of GitHub's weird rounding algorithm\n * for stars, forks and all other numbers. While all numbers below `1,000` are\n * returned as-is, bigger numbers are converted to fixed numbers:\n *\n * - `1,049` => `1k`\n * - `1,050` => `1.1k`\n * - `1,949` => `1.9k`\n * - `1,950` => `2k`\n *\n * @param value - Original value\n *\n * @returns Rounded value\n */\nexport function round(value: number): string {\n if (value > 999) {\n const digits = +((value - 950) % 1000 > 99)\n return `${((value + 0.000001) / 1000).toFixed(digits)}k`\n } else {\n return value.toString()\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n shareReplay,\n startWith\n} from \"rxjs\"\n\nimport { getOptionalElement } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location hash\n *\n * @returns Location hash\n */\nexport function getLocationHash(): string {\n return location.hash.substring(1)\n}\n\n/**\n * Set location hash\n *\n * Setting a new fragment identifier via `location.hash` will have no effect\n * if the value doesn't change. When a new fragment identifier is set, we want\n * the browser to target the respective element at all times, which is why we\n * use this dirty little trick.\n *\n * @param hash - Location hash\n */\nexport function setLocationHash(hash: string): void {\n const el = h(\"a\", { href: hash })\n el.addEventListener(\"click\", ev => ev.stopPropagation())\n el.click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location hash\n *\n * @returns Location hash observable\n */\nexport function watchLocationHash(): Observable {\n return fromEvent(window, \"hashchange\")\n .pipe(\n map(getLocationHash),\n startWith(getLocationHash()),\n filter(hash => hash.length > 0),\n shareReplay(1)\n )\n}\n\n/**\n * Watch location target\n *\n * @returns Location target observable\n */\nexport function watchLocationTarget(): Observable {\n return watchLocationHash()\n .pipe(\n map(id => getOptionalElement(`[id=\"${id}\"]`)!),\n filter(el => typeof el !== \"undefined\")\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n fromEvent,\n fromEventPattern,\n map,\n merge,\n startWith,\n switchMap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch media query\n *\n * Note that although `MediaQueryList.addListener` is deprecated we have to\n * use it, because it's the only way to ensure proper downward compatibility.\n *\n * @see https://bit.ly/3dUBH2m - GitHub issue\n *\n * @param query - Media query\n *\n * @returns Media observable\n */\nexport function watchMedia(query: string): Observable {\n const media = matchMedia(query)\n return fromEventPattern(next => (\n media.addListener(() => next(media.matches))\n ))\n .pipe(\n startWith(media.matches)\n )\n}\n\n/**\n * Watch print mode\n *\n * @returns Print observable\n */\nexport function watchPrint(): Observable {\n const media = matchMedia(\"print\")\n return merge(\n fromEvent(window, \"beforeprint\").pipe(map(() => true)),\n fromEvent(window, \"afterprint\").pipe(map(() => false))\n )\n .pipe(\n startWith(media.matches)\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Toggle an observable with a media observable\n *\n * @template T - Data type\n *\n * @param query$ - Media observable\n * @param factory - Observable factory\n *\n * @returns Toggled observable\n */\nexport function at(\n query$: Observable, factory: () => Observable\n): Observable {\n return query$\n .pipe(\n switchMap(active => active ? factory() : EMPTY)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n catchError,\n filter,\n from,\n map,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the given URL\n *\n * If the request fails (e.g. when dispatched from `file://` locations), the\n * observable will complete without emitting a value.\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Response observable\n */\nexport function request(\n url: URL | string, options: RequestInit = { credentials: \"same-origin\" }\n): Observable {\n return from(fetch(`${url}`, options))\n .pipe(\n filter(res => res.status === 200),\n catchError(() => EMPTY)\n )\n}\n\n/**\n * Fetch JSON from the given URL\n *\n * @template T - Data type\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestJSON(\n url: URL | string, options?: RequestInit\n): Observable {\n return request(url, options)\n .pipe(\n switchMap(res => res.json()),\n shareReplay(1)\n )\n}\n\n/**\n * Fetch XML from the given URL\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestXML(\n url: URL | string, options?: RequestInit\n): Observable {\n const dom = new DOMParser()\n return request(url, options)\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/xml\")),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n switchMap,\n take,\n throwError\n} from \"rxjs\"\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create and load a `script` element\n *\n * This function returns an observable that will emit when the script was\n * successfully loaded, or throw an error if it didn't.\n *\n * @param src - Script URL\n *\n * @returns Script observable\n */\nexport function watchScript(src: string): Observable {\n const script = h(\"script\", { src })\n return defer(() => {\n document.head.appendChild(script)\n return merge(\n fromEvent(script, \"load\"),\n fromEvent(script, \"error\")\n .pipe(\n switchMap(() => (\n throwError(() => new ReferenceError(`Invalid script: ${src}`))\n ))\n )\n )\n .pipe(\n map(() => undefined),\n finalize(() => document.head.removeChild(script)),\n take(1)\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport offset\n */\nexport interface ViewportOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport offset\n *\n * On iOS Safari, viewport offset can be negative due to overflow scrolling.\n * As this may induce strange behaviors downstream, we'll just limit it to 0.\n *\n * @returns Viewport offset\n */\nexport function getViewportOffset(): ViewportOffset {\n return {\n x: Math.max(0, scrollX),\n y: Math.max(0, scrollY)\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport offset\n *\n * @returns Viewport offset observable\n */\nexport function watchViewportOffset(): Observable {\n return merge(\n fromEvent(window, \"scroll\", { passive: true }),\n fromEvent(window, \"resize\", { passive: true })\n )\n .pipe(\n map(getViewportOffset),\n startWith(getViewportOffset())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport size\n */\nexport interface ViewportSize {\n width: number /* Viewport width */\n height: number /* Viewport height */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport size\n *\n * @returns Viewport size\n */\nexport function getViewportSize(): ViewportSize {\n return {\n width: innerWidth,\n height: innerHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport size\n *\n * @returns Viewport size observable\n */\nexport function watchViewportSize(): Observable {\n return fromEvent(window, \"resize\", { passive: true })\n .pipe(\n map(getViewportSize),\n startWith(getViewportSize())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n map,\n shareReplay\n} from \"rxjs\"\n\nimport {\n ViewportOffset,\n watchViewportOffset\n} from \"../offset\"\nimport {\n ViewportSize,\n watchViewportSize\n} from \"../size\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport\n */\nexport interface Viewport {\n offset: ViewportOffset /* Viewport offset */\n size: ViewportSize /* Viewport size */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport\n *\n * @returns Viewport observable\n */\nexport function watchViewport(): Observable {\n return combineLatest([\n watchViewportOffset(),\n watchViewportSize()\n ])\n .pipe(\n map(([offset, size]) => ({ offset, size })),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilKeyChanged,\n map\n} from \"rxjs\"\n\nimport { Header } from \"~/components\"\n\nimport { getElementOffset } from \"../../element\"\nimport { Viewport } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
/* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport relative to element\n *\n * @param el - Element\n * @param options - Options\n *\n * @returns Viewport observable\n */\nexport function watchViewportAt(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const size$ = viewport$\n .pipe(\n distinctUntilKeyChanged(\"size\")\n )\n\n /* Compute element offset */\n const offset$ = combineLatest([size$, header$])\n .pipe(\n map(() => getElementOffset(el))\n )\n\n /* Compute relative viewport, return hot observable */\n return combineLatest([header$, viewport$, offset$])\n .pipe(\n map(([{ height }, { offset, size }, { x, y }]) => ({\n offset: {\n x: offset.x - x,\n y: offset.y - y + height\n },\n size\n }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n fromEvent,\n map,\n share,\n switchMap,\n tap,\n throttle\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Worker message\n */\nexport interface WorkerMessage {\n type: unknown /* Message type */\n data?: unknown /* Message data */\n}\n\n/**\n * Worker handler\n *\n * @template T - Message type\n */\nexport interface WorkerHandler<\n T extends WorkerMessage\n> {\n tx$: Subject /* Message transmission subject */\n rx$: Observable /* Message receive observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n *\n * @template T - Worker message type\n */\ninterface WatchOptions {\n tx$: Observable /* Message transmission observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch a web worker\n *\n * This function returns an observable that sends all values emitted by the\n * message observable to the web worker. Web worker communication is expected\n * to be bidirectional (request-response) and synchronous. Messages that are\n * emitted during a pending request are throttled, the last one is emitted.\n *\n * @param worker - Web worker\n * @param options - Options\n *\n * @returns Worker message observable\n */\nexport function watchWorker(\n worker: Worker, { tx$ }: WatchOptions\n): Observable {\n\n /* Intercept messages from worker-like objects */\n const rx$ = fromEvent(worker, \"message\")\n .pipe(\n map(({ data }) => data as T)\n )\n\n /* Send and receive messages, return hot observable */\n return tx$\n .pipe(\n throttle(() => rx$, { leading: true, trailing: true }),\n tap(message => worker.postMessage(message)),\n switchMap(() => rx$),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getLocation } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flag\n */\nexport type Flag =\n | \"content.code.annotate\" /* Code annotations */\n | \"header.autohide\" /* Hide header */\n | \"navigation.expand\" /* Automatic expansion */\n | \"navigation.indexes\" /* Section pages */\n | \"navigation.instant\" /* Instant loading */\n | \"navigation.sections\" /* Section navigation */\n | \"navigation.tabs\" /* Tabs navigation */\n | \"navigation.tabs.sticky\" /* Tabs navigation (sticky) */\n | \"navigation.top\" /* Back-to-top button */\n | \"navigation.tracking\" /* Anchor tracking */\n | \"search.highlight\" /* Search highlighting */\n | \"search.share\" /* Search sharing */\n | \"search.suggest\" /* Search suggestions */\n | \"toc.integrate\" /* Integrated table of contents */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Translation\n */\nexport type Translation =\n | \"clipboard.copy\" /* Copy to clipboard */\n | \"clipboard.copied\" /* Copied to clipboard */\n | \"search.config.lang\" /* Search language */\n | \"search.config.pipeline\" /* Search pipeline */\n | \"search.config.separator\" /* Search separator */\n | \"search.placeholder\" /* Search */\n | \"search.result.placeholder\" /* Type to start searching */\n | \"search.result.none\" /* No matching documents */\n | \"search.result.one\" /* 1 matching document */\n | \"search.result.other\" /* # matching documents */\n | \"search.result.more.one\" /* 1 more on this page */\n | \"search.result.more.other\" /* # more on this page */\n | \"search.result.term.missing\" /* Missing */\n | \"select.version.title\" /* Version selector */\n\n/**\n * Translations\n */\nexport type Translations = Record\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Versioning\n */\nexport interface Versioning {\n provider: \"mike\" /* Version provider */\n default?: string /* Default version */\n}\n\n/**\n * Configuration\n */\nexport interface Config {\n base: string /* Base URL */\n features: Flag[] /* Feature flags */\n translations: Translations /* Translations */\n search: string /* Search worker URL */\n version?: Versioning /* Versioning */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration and make base URL absolute\n */\nconst script = getElement(\"#__config\")\nconst config: Config = JSON.parse(script.textContent!)\nconfig.base = `${new URL(config.base, getLocation())}`\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration\n *\n * @returns Global configuration\n */\nexport function configuration(): Config {\n return config\n}\n\n/**\n * Check whether a feature flag is enabled\n *\n * @param flag - Feature flag\n *\n * @returns Test result\n */\nexport function feature(flag: Flag): boolean {\n return config.features.includes(flag)\n}\n\n/**\n * Retrieve the translation for the given key\n *\n * @param key - Key to be translated\n * @param value - Positional value, if any\n *\n * @returns Translation\n */\nexport function translation(\n key: Translation, value?: string | number\n): string {\n return typeof value !== \"undefined\"\n ? config.translations[key].replace(\"#\", value.toString())\n : config.translations[key]\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type\n */\nexport type ComponentType =\n | \"announce\" /* Announcement bar */\n | \"container\" /* Container */\n | \"content\" /* Content */\n | \"dialog\" /* Dialog */\n | \"header\" /* Header */\n | \"header-title\" /* Header title */\n | \"header-topic\" /* Header topic */\n | \"main\" /* Main area */\n | \"outdated\" /* Version warning */\n | \"palette\" /* Color palette */\n | \"search\" /* Search */\n | \"search-query\" /* Search input */\n | \"search-result\" /* Search results */\n | \"search-share\" /* Search sharing */\n | \"search-suggest\" /* Search suggestions */\n | \"sidebar\" /* Sidebar */\n | \"skip\" /* Skip link */\n | \"source\" /* Repository information */\n | \"tabs\" /* Navigation tabs */\n | \"toc\" /* Table of contents */\n | \"top\" /* Back-to-top button */\n\n/**\n * Component\n *\n * @template T - Component type\n * @template U - Reference type\n */\nexport type Component<\n T extends {} = {},\n U extends HTMLElement = HTMLElement\n> =\n T & {\n ref: U /* Component reference */\n }\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type map\n */\ninterface ComponentTypeMap {\n \"announce\": HTMLElement /* Announcement bar */\n \"container\": HTMLElement /* Container */\n \"content\": HTMLElement /* Content */\n \"dialog\": HTMLElement /* Dialog */\n \"header\": HTMLElement /* Header */\n \"header-title\": HTMLElement /* Header title */\n \"header-topic\": HTMLElement /* Header topic */\n \"main\": HTMLElement /* Main area */\n \"outdated\": HTMLElement /* Version warning */\n \"palette\": HTMLElement /* Color palette */\n \"search\": HTMLElement /* Search */\n \"search-query\": HTMLInputElement /* Search input */\n \"search-result\": HTMLElement /* Search results */\n \"search-share\": HTMLAnchorElement /* Search sharing */\n \"search-suggest\": HTMLElement /* Search suggestions */\n \"sidebar\": HTMLElement /* Sidebar */\n \"skip\": HTMLAnchorElement /* Skip link */\n \"source\": HTMLAnchorElement /* Repository information */\n \"tabs\": HTMLElement /* Navigation tabs */\n \"toc\": HTMLElement /* Table of contents */\n \"top\": HTMLAnchorElement /* Back-to-top button */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the element for a given component or throw a reference error\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getComponentElement(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T] {\n return getElement(`[data-md-component=${type}]`, node)\n}\n\n/**\n * Retrieve all elements for a given component\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getComponentElements(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T][] {\n return getElements(`[data-md-component=${type}]`, node)\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n map,\n mergeWith,\n switchMap,\n take,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n getElementContentSize,\n watchElementSize,\n watchElementVisibility\n} from \"~/browser\"\nimport { renderClipboardButton } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotationList\n} from \"../../annotation\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Code block\n */\nexport interface CodeBlock {\n scrollable: boolean /* Code block overflows */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Global sequence number for Clipboard.js integration\n */\nlet sequence = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find candidate list element directly following a code block\n *\n * @param el - Code block element\n *\n * @returns List element or nothing\n */\nfunction findCandidateList(el: HTMLElement): HTMLElement | undefined {\n if (el.nextElementSibling) {\n const sibling = el.nextElementSibling as HTMLElement\n if (sibling.tagName === \"OL\")\n return sibling\n\n /* Skip empty paragraphs - see https://bit.ly/3r4ZJ2O */\n else if (sibling.tagName === \"P\" && !sibling.children.length)\n return findCandidateList(sibling)\n }\n\n /* Everything else */\n return undefined\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch code block\n *\n * This function monitors size changes of the viewport, as well as switches of\n * content tabs with embedded code blocks, as both may trigger overflow.\n *\n * @param el - Code block element\n *\n * @returns Code block observable\n */\nexport function watchCodeBlock(\n el: HTMLElement\n): Observable {\n return watchElementSize(el)\n .pipe(\n map(({ width }) => {\n const content = getElementContentSize(el)\n return {\n scrollable: content.width > width\n }\n }),\n distinctUntilKeyChanged(\"scrollable\")\n )\n}\n\n/**\n * Mount code block\n *\n * This function ensures that an overflowing code block is focusable through\n * keyboard, so it can be scrolled without a mouse to improve on accessibility.\n * Furthermore, if code annotations are enabled, they are mounted if and only\n * if the code block is currently visible, e.g., not in a hidden content tab.\n *\n * @param el - Code block element\n * @param options - Options\n *\n * @returns Code block and annotation component observable\n */\nexport function mountCodeBlock(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const { matches: hover } = matchMedia(\"(hover)\")\n\n /* Defer mounting of code block - see https://bit.ly/3vHVoVD */\n const factory$ = defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ scrollable }) => {\n if (scrollable && hover)\n el.setAttribute(\"tabindex\", \"0\")\n else\n el.removeAttribute(\"tabindex\")\n })\n\n /* Render button for Clipboard.js integration */\n if (ClipboardJS.isSupported()) {\n const parent = el.closest(\"pre\")!\n parent.id = `__code_${++sequence}`\n parent.insertBefore(\n renderClipboardButton(parent.id),\n el\n )\n }\n\n /* Handle code annotations */\n const container = el.closest([\n \":not(td):not(.code) > .highlight\",\n \".highlighttable\"\n ].join(\", \"))\n if (container instanceof HTMLElement) {\n const list = findCandidateList(container)\n\n /* Mount code annotations, if enabled */\n if (typeof list !== \"undefined\" && (\n container.classList.contains(\"annotate\") ||\n feature(\"content.code.annotate\")\n )) {\n const annotations$ = mountAnnotationList(list, el, options)\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state })),\n mergeWith(\n watchElementSize(container)\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n map(({ width, height }) => width && height),\n distinctUntilChanged(),\n switchMap(active => active ? annotations$ : EMPTY)\n )\n )\n )\n }\n }\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n\n /* Mount code block on first sight */\n return watchElementVisibility(el)\n .pipe(\n filter(visible => visible),\n take(1),\n switchMap(() => factory$)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render an empty annotation\n *\n * @param id - Annotation identifier\n *\n * @returns Element\n */\nexport function renderAnnotation(id: number): HTMLElement {\n return (\n \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a 'copy-to-clipboard' button\n *\n * @param id - Unique identifier\n *\n * @returns Element\n */\nexport function renderClipboardButton(id: string): HTMLElement {\n return (\n code`}\n >\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ComponentChild } from \"preact\"\n\nimport { feature, translation } from \"~/_\"\nimport {\n SearchDocument,\n SearchMetadata,\n SearchResultItem\n} from \"~/integrations/search\"\nimport { h, truncate } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Render flag\n */\nconst enum Flag {\n TEASER = 1, /* Render teaser */\n PARENT = 2 /* Render as parent */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper function\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search document\n *\n * @param document - Search document\n * @param flag - Render flags\n *\n * @returns Element\n */\nfunction renderSearchDocument(\n document: SearchDocument & SearchMetadata, flag: Flag\n): HTMLElement {\n const parent = flag & Flag.PARENT\n const teaser = flag & Flag.TEASER\n\n /* Render missing query terms */\n const missing = Object.keys(document.terms)\n .filter(key => !document.terms[key])\n .reduce((list, key) => [\n ...list, {key}, \" \"\n ], [])\n .slice(0, -1)\n\n /* Assemble query string for highlighting */\n const url = new URL(document.location)\n if (feature(\"search.highlight\"))\n url.searchParams.set(\"h\", Object.entries(document.terms)\n .filter(([, match]) => match)\n .reduce((highlight, [value]) => `${highlight} ${value}`.trim(), \"\")\n )\n\n /* Render article or section, depending on flags */\n return (\n \n \n {parent > 0 &&
}\n

{document.title}

\n {teaser > 0 && document.text.length > 0 &&\n

\n {truncate(document.text, 320)}\n

\n }\n {document.tags && document.tags.map(tag => (\n {tag}\n ))}\n {teaser > 0 && missing.length > 0 &&\n

\n {translation(\"search.result.term.missing\")}: {...missing}\n

\n }\n \n
\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search result\n *\n * @param result - Search result\n *\n * @returns Element\n */\nexport function renderSearchResultItem(\n result: SearchResultItem\n): HTMLElement {\n const threshold = result[0].score\n const docs = [...result]\n\n /* Find and extract parent article */\n const parent = docs.findIndex(doc => !doc.location.includes(\"#\"))\n const [article] = docs.splice(parent, 1)\n\n /* Determine last index above threshold */\n let index = docs.findIndex(doc => doc.score < threshold)\n if (index === -1)\n index = docs.length\n\n /* Partition sections */\n const best = docs.slice(0, index)\n const more = docs.slice(index)\n\n /* Render children */\n const children = [\n renderSearchDocument(article, Flag.PARENT | +(!parent && index === 0)),\n ...best.map(section => renderSearchDocument(section, Flag.TEASER)),\n ...more.length ? [\n
\n \n {more.length > 0 && more.length === 1\n ? translation(\"search.result.more.one\")\n : translation(\"search.result.more.other\", more.length)\n }\n \n {...more.map(section => renderSearchDocument(section, Flag.TEASER))}\n
\n ] : []\n ]\n\n /* Render search result */\n return (\n
  • \n {children}\n
  • \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SourceFacts } from \"~/components\"\nimport { h, round } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render repository facts\n *\n * @param facts - Repository facts\n *\n * @returns Element\n */\nexport function renderSourceFacts(facts: SourceFacts): HTMLElement {\n return (\n
      \n {Object.entries(facts).map(([key, value]) => (\n
    • \n {typeof value === \"number\" ? round(value) : value}\n
    • \n ))}\n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a table inside a wrapper to improve scrolling on mobile\n *\n * @param table - Table element\n *\n * @returns Element\n */\nexport function renderTable(table: HTMLElement): HTMLElement {\n return (\n
    \n
    \n {table}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { configuration, translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Version\n */\nexport interface Version {\n version: string /* Version identifier */\n title: string /* Version title */\n aliases: string[] /* Version aliases */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version\n *\n * @param version - Version\n *\n * @returns Element\n */\nfunction renderVersion(version: Version): HTMLElement {\n const config = configuration()\n\n /* Ensure trailing slash, see https://bit.ly/3rL5u3f */\n const url = new URL(`../${version.version}/`, config.base)\n return (\n
  • \n \n {version.title}\n \n
  • \n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version selector\n *\n * @param versions - Versions\n * @param active - Active version\n *\n * @returns Element\n */\nexport function renderVersionSelector(\n versions: Version[], active: Version\n): HTMLElement {\n return (\n
    \n \n {active.title}\n \n
      \n {versions.map(renderVersion)}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n animationFrameScheduler,\n combineLatest,\n defer,\n finalize,\n fromEvent,\n map,\n switchMap,\n take,\n tap,\n throttleTime\n} from \"rxjs\"\n\nimport {\n ElementOffset,\n getElement,\n getElementSize,\n watchElementContentOffset,\n watchElementFocus,\n watchElementOffset\n} from \"~/browser\"\n\nimport { Component } from \"../../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Annotation\n */\nexport interface Annotation {\n active: boolean /* Annotation is active */\n offset: ElementOffset /* Annotation offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n *\n * @returns Annotation observable\n */\nexport function watchAnnotation(\n el: HTMLElement, container: HTMLElement\n): Observable {\n const offset$ = defer(() => combineLatest([\n watchElementOffset(el),\n watchElementContentOffset(container)\n ]))\n .pipe(\n map(([{ x, y }, scroll]) => {\n const { width } = getElementSize(el)\n return ({\n x: x - scroll.x + width / 2,\n y: y - scroll.y\n })\n })\n )\n\n /* Actively watch annotation on focus */\n return watchElementFocus(el)\n .pipe(\n switchMap(active => offset$\n .pipe(\n map(offset => ({ active, offset })),\n take(+!active || Infinity)\n )\n )\n )\n}\n\n/**\n * Mount annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotation(\n el: HTMLElement, container: HTMLElement\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ offset }) {\n el.style.setProperty(\"--md-tooltip-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-tooltip-y\", `${offset.y}px`)\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-x\")\n el.style.removeProperty(\"--md-tooltip-y\")\n }\n })\n\n /* Track relative origin of tooltip */\n push$\n .pipe(\n throttleTime(500, animationFrameScheduler),\n map(() => container.getBoundingClientRect()),\n map(({ x }) => x)\n )\n .subscribe({\n\n /* Handle emission */\n next(origin) {\n if (origin)\n el.style.setProperty(\"--md-tooltip-0\", `${-origin}px`)\n else\n el.style.removeProperty(\"--md-tooltip-0\")\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-0\")\n }\n })\n\n /* Close open annotation on click */\n const index = getElement(\":scope > :last-child\", el)\n const blur$ = fromEvent(index, \"mousedown\", { once: true })\n push$\n .pipe(\n switchMap(({ active }) => active ? blur$ : EMPTY),\n tap(ev => ev.preventDefault())\n )\n .subscribe(() => el.blur())\n\n /* Create and return component */\n return watchAnnotation(el, container)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n finalize,\n merge,\n share,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport {\n getElement,\n getElements,\n getOptionalElement\n} from \"~/browser\"\nimport { renderAnnotation } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotation\n} from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find all annotation markers in the given code block\n *\n * @param container - Containing element\n *\n * @returns Annotation markers\n */\nfunction findAnnotationMarkers(container: HTMLElement): Text[] {\n const markers: Text[] = []\n for (const comment of getElements(\".c, .c1, .cm\", container)) {\n let match: RegExpExecArray | null\n\n /* Split text at marker and add to list */\n let text = comment.firstChild as Text\n if (text instanceof Text)\n while ((match = /\\((\\d+)\\)/.exec(text.textContent!))) {\n const marker = text.splitText(match.index)\n text = marker.splitText(match[0].length)\n markers.push(marker)\n }\n }\n return markers\n}\n\n/**\n * Swap the child nodes of two elements\n *\n * @param source - Source element\n * @param target - Target element\n */\nfunction swap(source: HTMLElement, target: HTMLElement): void {\n target.append(...Array.from(source.childNodes))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount annotation list\n *\n * This function analyzes the containing code block and checks for markers\n * referring to elements in the given annotation list. If no markers are found,\n * the list is left untouched. Otherwise, list elements are rendered as\n * annotations inside the code block.\n *\n * @param el - Annotation list element\n * @param container - Containing element\n * @param options - Options\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotationList(\n el: HTMLElement, container: HTMLElement, { print$ }: MountOptions\n): Observable> {\n\n /* Find and replace all markers with empty annotations */\n const annotations = new Map()\n for (const marker of findAnnotationMarkers(container)) {\n const [, id] = marker.textContent!.match(/\\((\\d+)\\)/)!\n if (getOptionalElement(`li:nth-child(${id})`, el)) {\n annotations.set(+id, renderAnnotation(+id))\n marker.replaceWith(annotations.get(+id)!)\n }\n }\n\n /* Keep list if there are no annotations to render */\n if (annotations.size === 0)\n return EMPTY\n\n /* Create and return component */\n return defer(() => {\n const done$ = new Subject()\n\n /* Handle print mode - see https://bit.ly/3rgPdpt */\n print$\n .pipe(\n takeUntil(done$.pipe(takeLast(1)))\n )\n .subscribe(active => {\n el.hidden = !active\n\n /* Show annotations in code block or list (print) */\n for (const [id, annotation] of annotations) {\n const inner = getElement(\".md-typeset\", annotation)\n const child = getElement(`li:nth-child(${id})`, el)\n if (!active)\n swap(child, inner)\n else\n swap(inner, child)\n }\n })\n\n /* Create and return component */\n return merge(...[...annotations]\n .map(([, annotation]) => (\n mountAnnotation(annotation, container)\n ))\n )\n .pipe(\n finalize(() => done$.complete()),\n share()\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { watchScript } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../../_\"\n\nimport themeCSS from \"./index.css\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid diagram\n */\nexport interface Mermaid {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid instance observable\n */\nlet mermaid$: Observable\n\n/**\n * Global index for Mermaid integration\n */\nlet index = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch Mermaid script\n *\n * @returns Mermaid scripts observable\n */\nfunction fetchScripts(): Observable {\n return typeof mermaid === \"undefined\" || mermaid instanceof Element\n ? watchScript(\"https://unpkg.com/mermaid@9.0.1/dist/mermaid.min.js\")\n : of(undefined)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount Mermaid diagram\n *\n * @param el - Code block element\n *\n * @returns Mermaid diagram component observable\n */\nexport function mountMermaid(\n el: HTMLElement\n): Observable> {\n el.classList.remove(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n mermaid$ ||= fetchScripts()\n .pipe(\n tap(() => mermaid.initialize({\n startOnLoad: false,\n themeCSS\n })),\n map(() => undefined),\n shareReplay(1)\n )\n\n /* Render diagram */\n mermaid$.subscribe(() => {\n el.classList.add(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n const id = `__mermaid_${index++}`\n const host = h(\"div\", { class: \"mermaid\" })\n mermaid.mermaidAPI.render(id, el.textContent, (svg: string) => {\n\n /* Create a shadow root and inject diagram */\n const shadow = host.attachShadow({ mode: \"closed\" })\n shadow.innerHTML = svg\n\n /* Replace code block with diagram */\n el.replaceWith(host)\n })\n })\n\n /* Create and return component */\n return mermaid$\n .pipe(\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n tap\n} from \"rxjs\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Details\n */\nexport interface Details {\n action: \"open\" | \"close\" /* Details state */\n reveal?: boolean /* Details is revealed */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch details\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details observable\n */\nexport function watchDetails(\n el: HTMLDetailsElement, { target$, print$ }: WatchOptions\n): Observable
    {\n let open = true\n return merge(\n\n /* Open and focus details on location target */\n target$\n .pipe(\n map(target => target.closest(\"details:not([open])\")!),\n filter(details => el === details),\n map(() => ({\n action: \"open\", reveal: true\n }) as Details)\n ),\n\n /* Open details on print and close afterwards */\n print$\n .pipe(\n filter(active => active || !open),\n tap(() => open = el.open),\n map(active => ({\n action: active ? \"open\" : \"close\"\n }) as Details)\n )\n )\n}\n\n/**\n * Mount details\n *\n * This function ensures that `details` tags are opened on anchor jumps and\n * prior to printing, so the whole content of the page is visible.\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details component observable\n */\nexport function mountDetails(\n el: HTMLDetailsElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n push$.subscribe(({ action, reveal }) => {\n if (action === \"open\")\n el.setAttribute(\"open\", \"\")\n else\n el.removeAttribute(\"open\")\n if (reveal)\n el.scrollIntoView()\n })\n\n /* Create and return component */\n return watchDetails(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, of } from \"rxjs\"\n\nimport { renderTable } from \"~/templates\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Data table\n */\nexport interface DataTable {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Sentinel for replacement\n */\nconst sentinel = h(\"table\")\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount data table\n *\n * This function wraps a data table in another scrollable container, so it can\n * be smoothly scrolled on smaller screen sizes and won't break the layout.\n *\n * @param el - Data table element\n *\n * @returns Data table component observable\n */\nexport function mountDataTable(\n el: HTMLElement\n): Observable> {\n el.replaceWith(sentinel)\n sentinel.replaceWith(renderTable(el))\n\n /* Create and return component */\n return of({ ref: el })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n asyncScheduler,\n auditTime,\n combineLatest,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n startWith,\n subscribeOn,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport {\n getElement,\n getElementOffset,\n getElementSize,\n getElements,\n watchElementSize\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content tabs\n */\nexport interface ContentTabs {\n active: HTMLLabelElement /* Active tab label */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch content tabs\n *\n * @param el - Content tabs element\n *\n * @returns Content tabs observable\n */\nexport function watchContentTabs(\n el: HTMLElement\n): Observable {\n const inputs = getElements(\":scope > input\", el)\n const active = inputs.find(input => input.checked) || inputs[0]\n return merge(...inputs.map(input => fromEvent(input, \"change\")\n .pipe(\n map(() => ({\n active: getElement(`label[for=${input.id}]`)\n }) as ContentTabs)\n )\n ))\n .pipe(\n startWith({\n active: getElement(`label[for=${active.id}]`)\n } as ContentTabs)\n )\n}\n\n/**\n * Mount content tabs\n *\n * This function scrolls the active tab into view. While this functionality is\n * provided by browsers as part of `scrollInfoView`, browsers will always also\n * scroll the vertical axis, which we do not want. Thus, we decided to provide\n * this functionality ourselves.\n *\n * @param el - Content tabs element\n *\n * @returns Content tabs component observable\n */\nexport function mountContentTabs(\n el: HTMLElement\n): Observable> {\n const container = getElement(\".tabbed-labels\", el)\n return defer(() => {\n const push$ = new Subject()\n combineLatest([push$, watchElementSize(el)])\n .pipe(\n auditTime(1, animationFrameScheduler),\n takeUntil(push$.pipe(takeLast(1)))\n )\n .subscribe({\n\n /* Handle emission */\n next([{ active }]) {\n const offset = getElementOffset(active)\n const { width } = getElementSize(active)\n\n /* Set tab indicator offset and width */\n el.style.setProperty(\"--md-indicator-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-indicator-width\", `${width}px`)\n\n /* Smoothly scroll container */\n container.scrollTo({\n behavior: \"smooth\",\n left: offset.x\n })\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-indicator-x\")\n el.style.removeProperty(\"--md-indicator-width\")\n }\n })\n\n /* Create and return component */\n return watchContentTabs(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n .pipe(\n subscribeOn(asyncScheduler)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, merge } from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Annotation } from \"../annotation\"\nimport {\n CodeBlock,\n Mermaid,\n mountCodeBlock,\n mountMermaid\n} from \"../code\"\nimport {\n Details,\n mountDetails\n} from \"../details\"\nimport {\n DataTable,\n mountDataTable\n} from \"../table\"\nimport {\n ContentTabs,\n mountContentTabs\n} from \"../tabs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content\n */\nexport type Content =\n | Annotation\n | ContentTabs\n | CodeBlock\n | Mermaid\n | DataTable\n | Details\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount content\n *\n * This function mounts all components that are found in the content of the\n * actual article, including code blocks, data tables and details.\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Content component observable\n */\nexport function mountContent(\n el: HTMLElement, { target$, print$ }: MountOptions\n): Observable> {\n return merge(\n\n /* Code blocks */\n ...getElements(\"pre:not(.mermaid) > code\", el)\n .map(child => mountCodeBlock(child, { print$ })),\n\n /* Mermaid diagrams */\n ...getElements(\"pre.mermaid\", el)\n .map(child => mountMermaid(child)),\n\n /* Data tables */\n ...getElements(\"table:not([class])\", el)\n .map(child => mountDataTable(child)),\n\n /* Details */\n ...getElements(\"details\", el)\n .map(child => mountDetails(child, { target$, print$ })),\n\n /* Content tabs */\n ...getElements(\"[data-tabs]\", el)\n .map(child => mountContentTabs(child))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n delay,\n finalize,\n map,\n merge,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Dialog\n */\nexport interface Dialog {\n message: string /* Dialog message */\n active: boolean /* Dialog is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n alert$: Subject /* Alert subject */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch dialog\n *\n * @param _el - Dialog element\n * @param options - Options\n *\n * @returns Dialog observable\n */\nexport function watchDialog(\n _el: HTMLElement, { alert$ }: WatchOptions\n): Observable {\n return alert$\n .pipe(\n switchMap(message => merge(\n of(true),\n of(false).pipe(delay(2000))\n )\n .pipe(\n map(active => ({ message, active }))\n )\n )\n )\n}\n\n/**\n * Mount dialog\n *\n * This function reveals the dialog in the right corner when a new alert is\n * emitted through the subject that is passed as part of the options.\n *\n * @param el - Dialog element\n * @param options - Options\n *\n * @returns Dialog component observable\n */\nexport function mountDialog(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const inner = getElement(\".md-typeset\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ message, active }) => {\n inner.textContent = message\n if (active)\n el.setAttribute(\"data-md-state\", \"open\")\n else\n el.removeAttribute(\"data-md-state\")\n })\n\n /* Create and return component */\n return watchDialog(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n combineLatestWith,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n of,\n shareReplay,\n startWith,\n switchMap,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchToggle\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Main } from \"../../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface Header {\n height: number /* Header visible height */\n hidden: boolean /* Header is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Compute whether the header is hidden\n *\n * If the user scrolls past a certain threshold, the header can be hidden when\n * scrolling down, and shown when scrolling up.\n *\n * @param options - Options\n *\n * @returns Toggle observable\n */\nfunction isHidden({ viewport$ }: WatchOptions): Observable {\n if (!feature(\"header.autohide\"))\n return of(false)\n\n /* Compute direction and turning point */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => [a < b, b] as const),\n distinctUntilKeyChanged(0)\n )\n\n /* Compute whether header should be hidden */\n const hidden$ = combineLatest([viewport$, direction$])\n .pipe(\n filter(([{ offset }, [, y]]) => Math.abs(y - offset.y) > 100),\n map(([, [direction]]) => direction),\n distinctUntilChanged()\n )\n\n /* Compute threshold for hiding */\n const search$ = watchToggle(\"search\")\n return combineLatest([viewport$, search$])\n .pipe(\n map(([{ offset }, search]) => offset.y > 400 && !search),\n distinctUntilChanged(),\n switchMap(active => active ? hidden$ : of(false)),\n startWith(false)\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header observable\n */\nexport function watchHeader(\n el: HTMLElement, options: WatchOptions\n): Observable
    {\n return defer(() => combineLatest([\n watchElementSize(el),\n isHidden(options)\n ]))\n .pipe(\n map(([{ height }, hidden]) => ({\n height,\n hidden\n })),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.hidden === b.hidden\n )),\n shareReplay(1)\n )\n}\n\n/**\n * Mount header\n *\n * This function manages the different states of the header, i.e. whether it's\n * hidden or rendered with a shadow. This depends heavily on the main area.\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header component observable\n */\nexport function mountHeader(\n el: HTMLElement, { header$, main$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n push$\n .pipe(\n distinctUntilKeyChanged(\"active\"),\n combineLatestWith(header$)\n )\n .subscribe(([{ active }, { hidden }]) => {\n if (active)\n el.setAttribute(\"data-md-state\", hidden ? \"hidden\" : \"shadow\")\n else\n el.removeAttribute(\"data-md-state\")\n })\n\n /* Link to main area */\n main$.subscribe(push$)\n\n /* Create and return component */\n return header$\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n tap\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElementSize,\n getOptionalElement,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Header } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface HeaderTitle {\n active: boolean /* Header title is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header title\n *\n * @param el - Heading element\n * @param options - Options\n *\n * @returns Header title observable\n */\nexport function watchHeaderTitle(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchViewportAt(el, { viewport$, header$ })\n .pipe(\n map(({ offset: { y } }) => {\n const { height } = getElementSize(el)\n return {\n active: y >= height\n }\n }),\n distinctUntilKeyChanged(\"active\")\n )\n}\n\n/**\n * Mount header title\n *\n * This function swaps the header title from the site title to the title of the\n * current page when the user scrolls past the first headline.\n *\n * @param el - Header title element\n * @param options - Options\n *\n * @returns Header title component observable\n */\nexport function mountHeaderTitle(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ active }) => {\n if (active)\n el.setAttribute(\"data-md-state\", \"active\")\n else\n el.removeAttribute(\"data-md-state\")\n })\n\n /* Obtain headline, if any */\n const heading = getOptionalElement(\"article h1\")\n if (typeof heading === \"undefined\")\n return EMPTY\n\n /* Create and return component */\n return watchHeaderTitle(heading, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n map,\n switchMap\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchElementSize\n} from \"~/browser\"\n\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Main area\n */\nexport interface Main {\n offset: number /* Main area top offset */\n height: number /* Main area visible height */\n active: boolean /* Main area is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch main area\n *\n * This function returns an observable that computes the visual parameters of\n * the main area which depends on the viewport vertical offset and height, as\n * well as the height of the header element, if the header is fixed.\n *\n * @param el - Main area element\n * @param options - Options\n *\n * @returns Main area observable\n */\nexport function watchMain(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable
    {\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n map(({ height }) => height),\n distinctUntilChanged()\n )\n\n /* Compute the main area's top and bottom borders */\n const border$ = adjust$\n .pipe(\n switchMap(() => watchElementSize(el)\n .pipe(\n map(({ height }) => ({\n top: el.offsetTop,\n bottom: el.offsetTop + height\n })),\n distinctUntilKeyChanged(\"bottom\")\n )\n )\n )\n\n /* Compute the main area's offset, visible height and if we scrolled past */\n return combineLatest([adjust$, border$, viewport$])\n .pipe(\n map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => {\n height = Math.max(0, height\n - Math.max(0, top - y, header)\n - Math.max(0, height + y - bottom)\n )\n return {\n offset: top - header,\n height,\n active: top - header <= y\n }\n }),\n distinctUntilChanged((a, b) => (\n a.offset === b.offset &&\n a.height === b.height &&\n a.active === b.active\n ))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n defer,\n finalize,\n fromEvent,\n map,\n mergeMap,\n observeOn,\n of,\n shareReplay,\n startWith,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Palette colors\n */\nexport interface PaletteColor {\n scheme?: string /* Color scheme */\n primary?: string /* Primary color */\n accent?: string /* Accent color */\n}\n\n/**\n * Palette\n */\nexport interface Palette {\n index: number /* Palette index */\n color: PaletteColor /* Palette colors */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch color palette\n *\n * @param inputs - Color palette element\n *\n * @returns Color palette observable\n */\nexport function watchPalette(\n inputs: HTMLInputElement[]\n): Observable {\n const current = __md_get(\"__palette\") || {\n index: inputs.findIndex(input => matchMedia(\n input.getAttribute(\"data-md-color-media\")!\n ).matches)\n }\n\n /* Emit changes in color palette */\n return of(...inputs)\n .pipe(\n mergeMap(input => fromEvent(input, \"change\")\n .pipe(\n map(() => input)\n )\n ),\n startWith(inputs[Math.max(0, current.index)]),\n map(input => ({\n index: inputs.indexOf(input),\n color: {\n scheme: input.getAttribute(\"data-md-color-scheme\"),\n primary: input.getAttribute(\"data-md-color-primary\"),\n accent: input.getAttribute(\"data-md-color-accent\")\n }\n } as Palette)),\n shareReplay(1)\n )\n}\n\n/**\n * Mount color palette\n *\n * @param el - Color palette element\n *\n * @returns Color palette component observable\n */\nexport function mountPalette(\n el: HTMLElement\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(palette => {\n document.body.setAttribute(\"data-md-color-switching\", \"\")\n\n /* Set color palette */\n for (const [key, value] of Object.entries(palette.color))\n document.body.setAttribute(`data-md-color-${key}`, value)\n\n /* Toggle visibility */\n for (let index = 0; index < inputs.length; index++) {\n const label = inputs[index].nextElementSibling\n if (label instanceof HTMLElement)\n label.hidden = palette.index !== index\n }\n\n /* Persist preference in local storage */\n __md_set(\"__palette\", palette)\n })\n\n /* Revert transition durations after color switch */\n push$.pipe(observeOn(asyncScheduler))\n .subscribe(() => {\n document.body.removeAttribute(\"data-md-color-switching\")\n })\n\n /* Create and return component */\n const inputs = getElements(\"input\", el)\n return watchPalette(inputs)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n Observable,\n Subject,\n map,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport { getElement } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Extract text to copy\n *\n * @param el - HTML element\n *\n * @returns Extracted text\n */\nfunction extract(el: HTMLElement): string {\n el.setAttribute(\"data-md-copying\", \"\")\n const text = el.innerText\n el.removeAttribute(\"data-md-copying\")\n return text\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up Clipboard.js integration\n *\n * @param options - Options\n */\nexport function setupClipboardJS(\n { alert$ }: SetupOptions\n): void {\n if (ClipboardJS.isSupported()) {\n new Observable(subscriber => {\n new ClipboardJS(\"[data-clipboard-target], [data-clipboard-text]\", {\n text: el => (\n el.getAttribute(\"data-clipboard-text\")! ||\n extract(getElement(\n el.getAttribute(\"data-clipboard-target\")!\n ))\n )\n })\n .on(\"success\", ev => subscriber.next(ev))\n })\n .pipe(\n tap(ev => {\n const trigger = ev.trigger as HTMLElement\n trigger.focus()\n }),\n map(() => translation(\"clipboard.copied\"))\n )\n .subscribe(alert$)\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n defaultIfEmpty,\n map,\n of,\n tap\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport { getElements, requestXML } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sitemap, i.e. a list of URLs\n */\nexport type Sitemap = string[]\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Preprocess a list of URLs\n *\n * This function replaces the `site_url` in the sitemap with the actual base\n * URL, to allow instant loading to work in occasions like Netlify previews.\n *\n * @param urls - URLs\n *\n * @returns URL path parts\n */\nfunction preprocess(urls: Sitemap): Sitemap {\n if (urls.length < 2)\n return [\"\"]\n\n /* Take the first two URLs and remove everything after the last slash */\n const [root, next] = [...urls]\n .sort((a, b) => a.length - b.length)\n .map(url => url.replace(/[^/]+$/, \"\"))\n\n /* Compute common prefix */\n let index = 0\n if (root === next)\n index = root.length\n else\n while (root.charCodeAt(index) === next.charCodeAt(index))\n index++\n\n /* Remove common prefix and return in original order */\n return urls.map(url => url.replace(root.slice(0, index), \"\"))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the sitemap for the given base URL\n *\n * @param base - Base URL\n *\n * @returns Sitemap observable\n */\nexport function fetchSitemap(base?: URL): Observable {\n const cached = __md_get(\"__sitemap\", sessionStorage, base)\n if (cached) {\n return of(cached)\n } else {\n const config = configuration()\n return requestXML(new URL(\"sitemap.xml\", base || config.base))\n .pipe(\n map(sitemap => preprocess(getElements(\"loc\", sitemap)\n .map(node => node.textContent!)\n )),\n defaultIfEmpty([]),\n tap(sitemap => __md_set(\"__sitemap\", sitemap, sessionStorage, base))\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n bufferCount,\n catchError,\n concatMap,\n debounceTime,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n fromEvent,\n map,\n merge,\n of,\n sample,\n share,\n skip,\n skipUntil,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"~/_\"\nimport {\n Viewport,\n ViewportOffset,\n getElements,\n getOptionalElement,\n request,\n setLocation,\n setLocationHash\n} from \"~/browser\"\nimport { getComponentElement } from \"~/components\"\nimport { h } from \"~/utilities\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * History state\n */\nexport interface HistoryState {\n url: URL /* State URL */\n offset?: ViewportOffset /* State viewport offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n location$: Subject /* Location subject */\n viewport$: Observable /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up instant loading\n *\n * When fetching, theoretically, we could use `responseType: \"document\"`, but\n * since all MkDocs links are relative, we need to make sure that the current\n * location matches the document we just loaded. Otherwise any relative links\n * in the document could use the old location.\n *\n * This is the reason why we need to synchronize history events and the process\n * of fetching the document for navigation changes (except `popstate` events):\n *\n * 1. Fetch document via `XMLHTTPRequest`\n * 2. Set new location via `history.pushState`\n * 3. Parse and emit fetched document\n *\n * For `popstate` events, we must not use `history.pushState`, or the forward\n * history will be irreversibly overwritten. In case the request fails, the\n * location change is dispatched regularly.\n *\n * @param options - Options\n */\nexport function setupInstantLoading(\n { document$, location$, viewport$ }: SetupOptions\n): void {\n const config = configuration()\n if (location.protocol === \"file:\")\n return\n\n /* Disable automatic scroll restoration */\n if (\"scrollRestoration\" in history) {\n history.scrollRestoration = \"manual\"\n\n /* Hack: ensure that reloads restore viewport offset */\n fromEvent(window, \"beforeunload\")\n .subscribe(() => {\n history.scrollRestoration = \"auto\"\n })\n }\n\n /* Hack: ensure absolute favicon link to omit 404s when switching */\n const favicon = getOptionalElement(\"link[rel=icon]\")\n if (typeof favicon !== \"undefined\")\n favicon.href = favicon.href\n\n /* Intercept internal navigation */\n const push$ = fetchSitemap()\n .pipe(\n map(paths => paths.map(path => `${new URL(path, config.base)}`)),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n switchMap(ev => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target) {\n const url = new URL(el.href)\n\n /* Canonicalize URL */\n url.search = \"\"\n url.hash = \"\"\n\n /* Check if URL should be intercepted */\n if (\n url.pathname !== location.pathname &&\n urls.includes(url.toString())\n ) {\n ev.preventDefault()\n return of({\n url: new URL(el.href)\n })\n }\n }\n }\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Intercept history back and forward */\n const pop$ = fromEvent(window, \"popstate\")\n .pipe(\n filter(ev => ev.state !== null),\n map(ev => ({\n url: new URL(location.href),\n offset: ev.state\n })),\n share()\n )\n\n /* Emit location change */\n merge(push$, pop$)\n .pipe(\n distinctUntilChanged((a, b) => a.url.href === b.url.href),\n map(({ url }) => url)\n )\n .subscribe(location$)\n\n /* Fetch document via `XMLHTTPRequest` */\n const response$ = location$\n .pipe(\n distinctUntilKeyChanged(\"pathname\"),\n switchMap(url => request(url.href)\n .pipe(\n catchError(() => {\n setLocation(url)\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Set new location via `history.pushState` */\n push$\n .pipe(\n sample(response$)\n )\n .subscribe(({ url }) => {\n history.pushState({}, \"\", `${url}`)\n })\n\n /* Parse and emit fetched document */\n const dom = new DOMParser()\n response$\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/html\"))\n )\n .subscribe(document$)\n\n /* Replace meta tags and components */\n document$\n .pipe(\n skip(1)\n )\n .subscribe(replacement => {\n for (const selector of [\n\n /* Meta tags */\n \"title\",\n \"link[rel=canonical]\",\n \"meta[name=author]\",\n \"meta[name=description]\",\n\n /* Components */\n \"[data-md-component=announce]\",\n \"[data-md-component=container]\",\n \"[data-md-component=header-topic]\",\n \"[data-md-component=outdated]\",\n \"[data-md-component=logo]\",\n \"[data-md-component=skip]\",\n ...feature(\"navigation.tabs.sticky\")\n ? [\"[data-md-component=tabs]\"]\n : []\n ]) {\n const source = getOptionalElement(selector)\n const target = getOptionalElement(selector, replacement)\n if (\n typeof source !== \"undefined\" &&\n typeof target !== \"undefined\"\n ) {\n source.replaceWith(target)\n }\n }\n })\n\n /* Re-evaluate scripts */\n document$\n .pipe(\n skip(1),\n map(() => getComponentElement(\"container\")),\n switchMap(el => getElements(\"script\", el)),\n concatMap(el => {\n const script = h(\"script\")\n if (el.src) {\n for (const name of el.getAttributeNames())\n script.setAttribute(name, el.getAttribute(name)!)\n el.replaceWith(script)\n\n /* Complete when script is loaded */\n return new Observable(observer => {\n script.onload = () => observer.complete()\n })\n\n /* Complete immediately */\n } else {\n script.textContent = el.textContent\n el.replaceWith(script)\n return EMPTY\n }\n })\n )\n .subscribe()\n\n /* Emit history state change */\n merge(push$, pop$)\n .pipe(\n sample(document$)\n )\n .subscribe(({ url, offset }) => {\n if (url.hash && !offset) {\n setLocationHash(url.hash)\n } else {\n window.scrollTo(0, offset?.y || 0)\n }\n })\n\n /* Debounce update of viewport offset */\n viewport$\n .pipe(\n skipUntil(push$),\n debounceTime(250),\n distinctUntilKeyChanged(\"offset\")\n )\n .subscribe(({ offset }) => {\n history.replaceState(offset, \"\")\n })\n\n /* Set viewport offset from history */\n merge(push$, pop$)\n .pipe(\n bufferCount(2, 1),\n filter(([a, b]) => a.url.pathname === b.url.pathname),\n map(([, state]) => state)\n )\n .subscribe(({ offset }) => {\n window.scrollTo(0, offset?.y || 0)\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexDocument } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search document\n */\nexport interface SearchDocument extends SearchIndexDocument {\n parent?: SearchIndexDocument /* Parent article */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search document mapping\n */\nexport type SearchDocumentMap = Map\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search document mapping\n *\n * @param docs - Search index documents\n *\n * @returns Search document map\n */\nexport function setupSearchDocumentMap(\n docs: SearchIndexDocument[]\n): SearchDocumentMap {\n const documents = new Map()\n const parents = new Set()\n for (const doc of docs) {\n const [path, hash] = doc.location.split(\"#\")\n\n /* Extract location, title and tags */\n const location = doc.location\n const title = doc.title\n const tags = doc.tags\n\n /* Escape and cleanup text */\n const text = escapeHTML(doc.text)\n .replace(/\\s+(?=[,.:;!?])/g, \"\")\n .replace(/\\s+/g, \" \")\n\n /* Handle section */\n if (hash) {\n const parent = documents.get(path)!\n\n /* Ignore first section, override article */\n if (!parents.has(parent)) {\n parent.title = doc.title\n parent.text = text\n\n /* Remember that we processed the article */\n parents.add(parent)\n\n /* Add subsequent section */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n parent\n })\n }\n\n /* Add article */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n ...tags && { tags }\n })\n }\n }\n return documents\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexConfig } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlight function\n *\n * @param value - Value\n *\n * @returns Highlighted value\n */\nexport type SearchHighlightFn = (value: string) => string\n\n/**\n * Search highlight factory function\n *\n * @param query - Query value\n *\n * @returns Search highlight function\n */\nexport type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search highlighter\n *\n * @param config - Search index configuration\n * @param escape - Whether to escape HTML\n *\n * @returns Search highlight factory function\n */\nexport function setupSearchHighlighter(\n config: SearchIndexConfig, escape: boolean\n): SearchHighlightFactoryFn {\n const separator = new RegExp(config.separator, \"img\")\n const highlight = (_: unknown, data: string, term: string) => {\n return `${data}${term}`\n }\n\n /* Return factory function */\n return (query: string) => {\n query = query\n .replace(/[\\s*+\\-:~^]+/g, \" \")\n .trim()\n\n /* Create search term match expression */\n const match = new RegExp(`(^|${config.separator})(${\n query\n .replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\")\n .replace(separator, \"|\")\n })`, \"img\")\n\n /* Highlight string value */\n return value => (\n escape\n ? escapeHTML(value)\n : value\n )\n .replace(match, highlight)\n .replace(/<\\/mark>(\\s+)]*>/img, \"$1\")\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search transformation function\n *\n * @param value - Query value\n *\n * @returns Transformed query value\n */\nexport type SearchTransformFn = (value: string) => string\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Default transformation function\n *\n * 1. Search for terms in quotation marks and prepend a `+` modifier to denote\n * that the resulting document must contain all terms, converting the query\n * to an `AND` query (as opposed to the default `OR` behavior). While users\n * may expect terms enclosed in quotation marks to map to span queries, i.e.\n * for which order is important, Lunr.js doesn't support them, so the best\n * we can do is to convert the terms to an `AND` query.\n *\n * 2. Replace control characters which are not located at the beginning of the\n * query or preceded by white space, or are not followed by a non-whitespace\n * character or are at the end of the query string. Furthermore, filter\n * unmatched quotation marks.\n *\n * 3. Trim excess whitespace from left and right.\n *\n * @param query - Query value\n *\n * @returns Transformed query value\n */\nexport function defaultTransform(query: string): string {\n return query\n .split(/\"([^\"]+)\"/g) /* => 1 */\n .map((terms, index) => index & 1\n ? terms.replace(/^\\b|^(?![^\\x00-\\x7F]|$)|\\s+/g, \" +\")\n : terms\n )\n .join(\"\")\n .replace(/\"|(?:^|\\s+)[*+\\-:^~]+(?=\\s+|$)/g, \"\") /* => 2 */\n .trim() /* => 3 */\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SearchIndex, SearchResult } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search message type\n */\nexport const enum SearchMessageType {\n SETUP, /* Search index setup */\n READY, /* Search index ready */\n QUERY, /* Search query */\n RESULT /* Search results */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message containing the data necessary to setup the search index\n */\nexport interface SearchSetupMessage {\n type: SearchMessageType.SETUP /* Message type */\n data: SearchIndex /* Message data */\n}\n\n/**\n * Message indicating the search index is ready\n */\nexport interface SearchReadyMessage {\n type: SearchMessageType.READY /* Message type */\n}\n\n/**\n * Message containing a search query\n */\nexport interface SearchQueryMessage {\n type: SearchMessageType.QUERY /* Message type */\n data: string /* Message data */\n}\n\n/**\n * Message containing results for a search query\n */\nexport interface SearchResultMessage {\n type: SearchMessageType.RESULT /* Message type */\n data: SearchResult /* Message data */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message exchanged with the search worker\n */\nexport type SearchMessage =\n | SearchSetupMessage\n | SearchReadyMessage\n | SearchQueryMessage\n | SearchResultMessage\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Type guard for search setup messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchSetupMessage(\n message: SearchMessage\n): message is SearchSetupMessage {\n return message.type === SearchMessageType.SETUP\n}\n\n/**\n * Type guard for search ready messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchReadyMessage(\n message: SearchMessage\n): message is SearchReadyMessage {\n return message.type === SearchMessageType.READY\n}\n\n/**\n * Type guard for search query messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchQueryMessage(\n message: SearchMessage\n): message is SearchQueryMessage {\n return message.type === SearchMessageType.QUERY\n}\n\n/**\n * Type guard for search result messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchResultMessage(\n message: SearchMessage\n): message is SearchResultMessage {\n return message.type === SearchMessageType.RESULT\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ObservableInput,\n Subject,\n from,\n map,\n share\n} from \"rxjs\"\n\nimport { configuration, feature, translation } from \"~/_\"\nimport { WorkerHandler, watchWorker } from \"~/browser\"\n\nimport { SearchIndex } from \"../../_\"\nimport {\n SearchOptions,\n SearchPipeline\n} from \"../../options\"\nimport {\n SearchMessage,\n SearchMessageType,\n SearchSetupMessage,\n isSearchResultMessage\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search worker\n */\nexport type SearchWorker = WorkerHandler\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search index\n *\n * @param data - Search index\n *\n * @returns Search index\n */\nfunction setupSearchIndex({ config, docs }: SearchIndex): SearchIndex {\n\n /* Override default language with value from translation */\n if (config.lang.length === 1 && config.lang[0] === \"en\")\n config.lang = [\n translation(\"search.config.lang\")\n ]\n\n /* Override default separator with value from translation */\n if (config.separator === \"[\\\\s\\\\-]+\")\n config.separator = translation(\"search.config.separator\")\n\n /* Set pipeline from translation */\n const pipeline = translation(\"search.config.pipeline\")\n .split(/\\s*,\\s*/)\n .filter(Boolean) as SearchPipeline\n\n /* Determine search options */\n const options: SearchOptions = {\n pipeline,\n suggestions: feature(\"search.suggest\")\n }\n\n /* Return search index after defaulting */\n return { config, docs, options }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search worker\n *\n * This function creates a web worker to set up and query the search index,\n * which is done using Lunr.js. The index must be passed as an observable to\n * enable hacks like _localsearch_ via search index embedding as JSON.\n *\n * @param url - Worker URL\n * @param index - Search index observable input\n *\n * @returns Search worker\n */\nexport function setupSearchWorker(\n url: string, index: ObservableInput\n): SearchWorker {\n const config = configuration()\n const worker = new Worker(url)\n\n /* Create communication channels and resolve relative links */\n const tx$ = new Subject()\n const rx$ = watchWorker(worker, { tx$ })\n .pipe(\n map(message => {\n if (isSearchResultMessage(message)) {\n for (const result of message.data.items)\n for (const document of result)\n document.location = `${new URL(document.location, config.base)}`\n }\n return message\n }),\n share()\n )\n\n /* Set up search index */\n from(index)\n .pipe(\n map(data => ({\n type: SearchMessageType.SETUP,\n data: setupSearchIndex(data)\n } as SearchSetupMessage))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Return search worker */\n return { tx$, rx$ }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Subject,\n combineLatest,\n filter,\n fromEvent,\n map,\n of,\n switchMap\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n getElement,\n getLocation,\n requestJSON,\n setLocation\n} from \"~/browser\"\nimport { getComponentElements } from \"~/components\"\nimport {\n Version,\n renderVersionSelector\n} from \"~/templates\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up version selector\n *\n * @param options - Options\n */\nexport function setupVersionSelector(\n { document$ }: SetupOptions\n): void {\n const config = configuration()\n const versions$ = requestJSON(\n new URL(\"../versions.json\", config.base)\n )\n\n /* Determine current version */\n const current$ = versions$\n .pipe(\n map(versions => {\n const [, current] = config.base.match(/([^/]+)\\/?$/)!\n return versions.find(({ version, aliases }) => (\n version === current || aliases.includes(current)\n )) || versions[0]\n })\n )\n\n /* Intercept inter-version navigation */\n combineLatest([versions$, current$])\n .pipe(\n map(([versions, current]) => new Map(versions\n .filter(version => version !== current)\n .map(version => [\n `${new URL(`../${version.version}/`, config.base)}`,\n version\n ])\n )),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n switchMap(ev => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target && urls.has(el.href)) {\n ev.preventDefault()\n return of(el.href)\n }\n }\n return EMPTY\n }),\n switchMap(url => {\n const { version } = urls.get(url)!\n return fetchSitemap(new URL(url))\n .pipe(\n map(sitemap => {\n const location = getLocation()\n const path = location.href.replace(config.base, \"\")\n return sitemap.includes(path)\n ? new URL(`../${version}/${path}`, config.base)\n : new URL(url)\n })\n )\n })\n )\n )\n )\n .subscribe(url => setLocation(url))\n\n /* Render version selector and warning */\n combineLatest([versions$, current$])\n .subscribe(([versions, current]) => {\n const topic = getElement(\".md-header__topic\")\n topic.appendChild(renderVersionSelector(versions, current))\n })\n\n /* Integrate outdated version banner with instant loading */\n document$.pipe(switchMap(() => current$))\n .subscribe(current => {\n\n /* Check if version state was already determined */\n let outdated = __md_get(\"__outdated\", sessionStorage)\n if (outdated === null) {\n const latest = config.version?.default || \"latest\"\n outdated = !current.aliases.includes(latest)\n\n /* Persist version state in session storage */\n __md_set(\"__outdated\", outdated, sessionStorage)\n }\n\n /* Unhide outdated version banner */\n if (outdated)\n for (const warning of getComponentElements(\"outdated\"))\n warning.hidden = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n combineLatest,\n delay,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n shareReplay,\n startWith,\n take,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getLocation,\n setToggle,\n watchElementFocus,\n watchToggle\n} from \"~/browser\"\nimport {\n SearchMessageType,\n SearchQueryMessage,\n SearchWorker,\n defaultTransform,\n isSearchReadyMessage\n} from \"~/integrations\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query\n */\nexport interface SearchQuery {\n value: string /* Query value */\n focus: boolean /* Query focus */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch search query\n *\n * Note that the focus event which triggers re-reading the current query value\n * is delayed by `1ms` so the input's empty state is allowed to propagate.\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query observable\n */\nexport function watchSearchQuery(\n el: HTMLInputElement, { rx$ }: SearchWorker\n): Observable {\n const fn = __search?.transform || defaultTransform\n\n /* Immediately show search dialog */\n const { searchParams } = getLocation()\n if (searchParams.has(\"q\"))\n setToggle(\"search\", true)\n\n /* Intercept query parameter (deep link) */\n const param$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1),\n map(() => searchParams.get(\"q\") || \"\")\n )\n\n /* Remove query parameter when search is closed */\n watchToggle(\"search\")\n .pipe(\n filter(active => !active),\n take(1)\n )\n .subscribe(() => {\n const url = new URL(location.href)\n url.searchParams.delete(\"q\")\n history.replaceState({}, \"\", `${url}`)\n })\n\n /* Set query from parameter */\n param$.subscribe(value => { // TODO: not ideal - find a better way\n if (value) {\n el.value = value\n el.focus()\n }\n })\n\n /* Intercept focus and input events */\n const focus$ = watchElementFocus(el)\n const value$ = merge(\n fromEvent(el, \"keyup\"),\n fromEvent(el, \"focus\").pipe(delay(1)),\n param$\n )\n .pipe(\n map(() => fn(el.value)),\n startWith(\"\"),\n distinctUntilChanged(),\n )\n\n /* Combine into single observable */\n return combineLatest([value$, focus$])\n .pipe(\n map(([value, focus]) => ({ value, focus })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount search query\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query component observable\n */\nexport function mountSearchQuery(\n el: HTMLInputElement, { tx$, rx$ }: SearchWorker\n): Observable> {\n const push$ = new Subject()\n\n /* Handle value changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"value\"),\n map(({ value }): SearchQueryMessage => ({\n type: SearchMessageType.QUERY,\n data: value\n }))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Handle focus changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"focus\")\n )\n .subscribe(({ focus }) => {\n if (focus) {\n setToggle(\"search\", focus)\n el.placeholder = \"\"\n } else {\n el.placeholder = translation(\"search.placeholder\")\n }\n })\n\n /* Handle reset */\n fromEvent(el.form!, \"reset\")\n .pipe(\n takeUntil(push$.pipe(takeLast(1)))\n )\n .subscribe(() => el.focus())\n\n /* Create and return component */\n return watchSearchQuery(el, { tx$, rx$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n filter,\n finalize,\n map,\n merge,\n of,\n skipUntil,\n switchMap,\n take,\n tap,\n withLatestFrom,\n zipWith\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getElement,\n watchElementBoundary\n} from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchReadyMessage,\n isSearchResultMessage\n} from \"~/integrations\"\nimport { renderSearchResultItem } from \"~/templates\"\nimport { round } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search result list\n *\n * This function performs a lazy rendering of the search results, depending on\n * the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchResult(\n el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n const boundary$ = watchElementBoundary(el.parentElement!)\n .pipe(\n filter(Boolean)\n )\n\n /* Retrieve nested components */\n const meta = getElement(\":scope > :first-child\", el)\n const list = getElement(\":scope > :last-child\", el)\n\n /* Wait until search is ready */\n const ready$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1)\n )\n\n /* Update search result metadata */\n push$\n .pipe(\n withLatestFrom(query$),\n skipUntil(ready$)\n )\n .subscribe(([{ items }, { value }]) => {\n if (value) {\n switch (items.length) {\n\n /* No results */\n case 0:\n meta.textContent = translation(\"search.result.none\")\n break\n\n /* One result */\n case 1:\n meta.textContent = translation(\"search.result.one\")\n break\n\n /* Multiple result */\n default:\n meta.textContent = translation(\n \"search.result.other\",\n round(items.length)\n )\n }\n } else {\n meta.textContent = translation(\"search.result.placeholder\")\n }\n })\n\n /* Update search result list */\n push$\n .pipe(\n tap(() => list.innerHTML = \"\"),\n switchMap(({ items }) => merge(\n of(...items.slice(0, 10)),\n of(...items.slice(10))\n .pipe(\n bufferCount(4),\n zipWith(boundary$),\n switchMap(([chunk]) => chunk)\n )\n ))\n )\n .subscribe(result => list.appendChild(\n renderSearchResultItem(result)\n ))\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n finalize,\n fromEvent,\n map,\n tap\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search sharing\n */\nexport interface SearchShare {\n url: URL /* Deep link for sharing */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n query$: Observable /* Search query observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search sharing\n *\n * @param _el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing observable\n */\nexport function watchSearchShare(\n _el: HTMLElement, { query$ }: WatchOptions\n): Observable {\n return query$\n .pipe(\n map(({ value }) => {\n const url = getLocation()\n url.hash = \"\"\n url.searchParams.delete(\"h\")\n url.searchParams.set(\"q\", value)\n return { url }\n })\n )\n}\n\n/**\n * Mount search sharing\n *\n * @param el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing component observable\n */\nexport function mountSearchShare(\n el: HTMLAnchorElement, options: MountOptions\n): Observable> {\n const push$ = new Subject()\n push$.subscribe(({ url }) => {\n el.setAttribute(\"data-clipboard-text\", el.href)\n el.href = `${url}`\n })\n\n /* Prevent following of link */\n fromEvent(el, \"click\")\n .subscribe(ev => ev.preventDefault())\n\n /* Create and return component */\n return watchSearchShare(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n combineLatestWith,\n distinctUntilChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n observeOn,\n tap\n} from \"rxjs\"\n\nimport { Keyboard } from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchResultMessage\n} from \"~/integrations\"\n\nimport { Component, getComponentElement } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search suggestions\n */\nexport interface SearchSuggest {}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search suggestions\n *\n * This function will perform a lazy rendering of the search results, depending\n * on the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchSuggest(\n el: HTMLElement, { rx$ }: SearchWorker, { keyboard$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n\n /* Retrieve query component and track all changes */\n const query = getComponentElement(\"search-query\")\n const query$ = merge(\n fromEvent(query, \"keydown\"),\n fromEvent(query, \"focus\")\n )\n .pipe(\n observeOn(asyncScheduler),\n map(() => query.value),\n distinctUntilChanged(),\n )\n\n /* Update search suggestions */\n push$\n .pipe(\n combineLatestWith(query$),\n map(([{ suggestions }, value]) => {\n const words = value.split(/([\\s-]+)/)\n if (suggestions?.length && words[words.length - 1]) {\n const last = suggestions[suggestions.length - 1]\n if (last.startsWith(words[words.length - 1]))\n words[words.length - 1] = last\n } else {\n words.length = 0\n }\n return words\n })\n )\n .subscribe(words => el.innerHTML = words\n .join(\"\")\n .replace(/\\s/g, \" \")\n )\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Right arrow: accept current suggestion */\n case \"ArrowRight\":\n if (\n el.innerText.length &&\n query.selectionStart === query.value.length\n )\n query.value = el.innerText\n break\n }\n })\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n ObservableInput,\n filter,\n merge,\n mergeWith,\n sample,\n take\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n Keyboard,\n getActiveElement,\n getElements,\n setToggle\n} from \"~/browser\"\nimport {\n SearchIndex,\n SearchResult,\n isSearchQueryMessage,\n isSearchReadyMessage,\n setupSearchWorker\n} from \"~/integrations\"\n\nimport {\n Component,\n getComponentElement,\n getComponentElements\n} from \"../../_\"\nimport {\n SearchQuery,\n mountSearchQuery\n} from \"../query\"\nimport { mountSearchResult } from \"../result\"\nimport {\n SearchShare,\n mountSearchShare\n} from \"../share\"\nimport {\n SearchSuggest,\n mountSearchSuggest\n} from \"../suggest\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search\n */\nexport type Search =\n | SearchQuery\n | SearchResult\n | SearchShare\n | SearchSuggest\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search\n *\n * This function sets up the search functionality, including the underlying\n * web worker and all keyboard bindings.\n *\n * @param el - Search element\n * @param options - Options\n *\n * @returns Search component observable\n */\nexport function mountSearch(\n el: HTMLElement, { index$, keyboard$ }: MountOptions\n): Observable> {\n const config = configuration()\n try {\n const url = __search?.worker || config.search\n const worker = setupSearchWorker(url, index$)\n\n /* Retrieve query and result components */\n const query = getComponentElement(\"search-query\", el)\n const result = getComponentElement(\"search-result\", el)\n\n /* Re-emit query when search is ready */\n const { tx$, rx$ } = worker\n tx$\n .pipe(\n filter(isSearchQueryMessage),\n sample(rx$.pipe(filter(isSearchReadyMessage))),\n take(1)\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n const active = getActiveElement()\n switch (key.type) {\n\n /* Enter: go to first (best) result */\n case \"Enter\":\n if (active === query) {\n const anchors = new Map()\n for (const anchor of getElements(\n \":first-child [href]\", result\n )) {\n const article = anchor.firstElementChild!\n anchors.set(anchor, parseFloat(\n article.getAttribute(\"data-md-score\")!\n ))\n }\n\n /* Go to result with highest score, if any */\n if (anchors.size) {\n const [[best]] = [...anchors].sort(([, a], [, b]) => b - a)\n best.click()\n }\n\n /* Otherwise omit form submission */\n key.claim()\n }\n break\n\n /* Escape or Tab: close search */\n case \"Escape\":\n case \"Tab\":\n setToggle(\"search\", false)\n query.blur()\n break\n\n /* Vertical arrows: select previous or next search result */\n case \"ArrowUp\":\n case \"ArrowDown\":\n if (typeof active === \"undefined\") {\n query.focus()\n } else {\n const els = [query, ...getElements(\n \":not(details) > [href], summary, details[open] [href]\",\n result\n )]\n const i = Math.max(0, (\n Math.max(0, els.indexOf(active)) + els.length + (\n key.type === \"ArrowUp\" ? -1 : +1\n )\n ) % els.length)\n els[i].focus()\n }\n\n /* Prevent scrolling of page */\n key.claim()\n break\n\n /* All other keys: hand to search query */\n default:\n if (query !== getActiveElement())\n query.focus()\n }\n })\n\n /* Set up global keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\"),\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Open search and select query */\n case \"f\":\n case \"s\":\n case \"/\":\n query.focus()\n query.select()\n\n /* Prevent scrolling of page */\n key.claim()\n break\n }\n })\n\n /* Create and return component */\n const query$ = mountSearchQuery(query, worker)\n const result$ = mountSearchResult(result, worker, { query$ })\n return merge(query$, result$)\n .pipe(\n mergeWith(\n\n /* Search sharing */\n ...getComponentElements(\"search-share\", el)\n .map(child => mountSearchShare(child, { query$ })),\n\n /* Search suggestions */\n ...getComponentElements(\"search-suggest\", el)\n .map(child => mountSearchSuggest(child, worker, { keyboard$ }))\n )\n )\n\n /* Gracefully handle broken search */\n } catch (err) {\n el.hidden = true\n return NEVER\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n ObservableInput,\n combineLatest,\n filter,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\nimport {\n SearchIndex,\n setupSearchHighlighter\n} from \"~/integrations\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlighting\n */\nexport interface SearchHighlight {\n nodes: Map /* Map of replacements */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n location$: Observable /* Location observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search highlighting\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Search highlighting component observable\n */\nexport function mountSearchHiglight(\n el: HTMLElement, { index$, location$ }: MountOptions\n): Observable> {\n return combineLatest([\n index$,\n location$\n .pipe(\n startWith(getLocation()),\n filter(url => !!url.searchParams.get(\"h\"))\n )\n ])\n .pipe(\n map(([index, url]) => setupSearchHighlighter(index.config, true)(\n url.searchParams.get(\"h\")!\n )),\n map(fn => {\n const nodes = new Map()\n\n /* Traverse text nodes and collect matches */\n const it = document.createNodeIterator(el, NodeFilter.SHOW_TEXT)\n for (let node = it.nextNode(); node; node = it.nextNode()) {\n if (node.parentElement?.offsetHeight) {\n const original = node.textContent!\n const replaced = fn(original)\n if (replaced.length > original.length)\n nodes.set(node as ChildNode, replaced)\n }\n }\n\n /* Replace original nodes with matches */\n for (const [node, text] of nodes) {\n const { childNodes } = h(\"span\", null, text)\n node.replaceWith(...Array.from(childNodes))\n }\n\n /* Return component */\n return { ref: el, nodes }\n })\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n auditTime,\n combineLatest,\n defer,\n distinctUntilChanged,\n finalize,\n map,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElement,\n getElementOffset\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sidebar\n */\nexport interface Sidebar {\n height: number /* Sidebar height */\n locked: boolean /* Sidebar is locked */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch sidebar\n *\n * This function returns an observable that computes the visual parameters of\n * the sidebar which depends on the vertical viewport offset, as well as the\n * height of the main area. When the page is scrolled beyond the header, the\n * sidebar is locked and fills the remaining space.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar observable\n */\nexport function watchSidebar(\n el: HTMLElement, { viewport$, main$ }: WatchOptions\n): Observable {\n const parent = el.parentElement!\n const adjust =\n parent.offsetTop -\n parent.parentElement!.offsetTop\n\n /* Compute the sidebar's available height and if it should be locked */\n return combineLatest([main$, viewport$])\n .pipe(\n map(([{ offset, height }, { offset: { y } }]) => {\n height = height\n + Math.min(adjust, Math.max(0, y - offset))\n - adjust\n return {\n height,\n locked: y >= offset + adjust\n }\n }),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.locked === b.locked\n ))\n )\n}\n\n/**\n * Mount sidebar\n *\n * This function doesn't set the height of the actual sidebar, but of its first\n * child \u2013 the `.md-sidebar__scrollwrap` element in order to mitigiate jittery\n * sidebars when the footer is scrolled into view. At some point we switched\n * from `absolute` / `fixed` positioning to `sticky` positioning, significantly\n * reducing jitter in some browsers (respectively Firefox and Safari) when\n * scrolling from the top. However, top-aligned sticky positioning means that\n * the sidebar snaps to the bottom when the end of the container is reached.\n * This is what leads to the mentioned jitter, as the sidebar's height may be\n * updated too slowly.\n *\n * This behaviour can be mitigiated by setting the height of the sidebar to `0`\n * while preserving the padding, and the height on its first element.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar component observable\n */\nexport function mountSidebar(\n el: HTMLElement, { header$, ...options }: MountOptions\n): Observable> {\n const inner = getElement(\".md-sidebar__scrollwrap\", el)\n const { y } = getElementOffset(inner)\n return defer(() => {\n const push$ = new Subject()\n push$\n .pipe(\n auditTime(0, animationFrameScheduler),\n withLatestFrom(header$)\n )\n .subscribe({\n\n /* Handle emission */\n next([{ height }, { height: offset }]) {\n inner.style.height = `${height - 2 * y}px`\n el.style.top = `${offset}px`\n },\n\n /* Handle complete */\n complete() {\n inner.style.height = \"\"\n el.style.top = \"\"\n }\n })\n\n /* Create and return component */\n return watchSidebar(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Repo, User } from \"github-types\"\nimport {\n Observable,\n defaultIfEmpty,\n map,\n zip\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * GitHub release (partial)\n */\ninterface Release {\n tag_name: string /* Tag name */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitHub repository facts\n *\n * @param user - GitHub user or organization\n * @param repo - GitHub repository\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitHub(\n user: string, repo?: string\n): Observable {\n if (typeof repo !== \"undefined\") {\n const url = `https://api.github.com/repos/${user}/${repo}`\n return zip(\n\n /* Fetch version */\n requestJSON(`${url}/releases/latest`)\n .pipe(\n map(release => ({\n version: release.tag_name\n })),\n defaultIfEmpty({})\n ),\n\n /* Fetch stars and forks */\n requestJSON(url)\n .pipe(\n map(info => ({\n stars: info.stargazers_count,\n forks: info.forks_count\n })),\n defaultIfEmpty({})\n )\n )\n .pipe(\n map(([release, info]) => ({ ...release, ...info }))\n )\n\n /* User or organization */\n } else {\n const url = `https://api.github.com/users/${user}`\n return requestJSON(url)\n .pipe(\n map(info => ({\n repositories: info.public_repos\n })),\n defaultIfEmpty({})\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ProjectSchema } from \"gitlab\"\nimport {\n Observable,\n defaultIfEmpty,\n map\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitLab repository facts\n *\n * @param base - GitLab base\n * @param project - GitLab project\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitLab(\n base: string, project: string\n): Observable {\n const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}`\n return requestJSON(url)\n .pipe(\n map(({ star_count, forks_count }) => ({\n stars: star_count,\n forks: forks_count\n })),\n defaultIfEmpty({})\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { EMPTY, Observable } from \"rxjs\"\n\nimport { fetchSourceFactsFromGitHub } from \"../github\"\nimport { fetchSourceFactsFromGitLab } from \"../gitlab\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository facts for repositories\n */\nexport interface RepositoryFacts {\n stars?: number /* Number of stars */\n forks?: number /* Number of forks */\n version?: string /* Latest version */\n}\n\n/**\n * Repository facts for organizations\n */\nexport interface OrganizationFacts {\n repositories?: number /* Number of repositories */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Repository facts\n */\nexport type SourceFacts =\n | RepositoryFacts\n | OrganizationFacts\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch repository facts\n *\n * @param url - Repository URL\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFacts(\n url: string\n): Observable {\n const [type] = url.match(/(git(?:hub|lab))/i) || []\n switch (type.toLowerCase()) {\n\n /* GitHub repository */\n case \"github\":\n const [, user, repo] = url.match(/^.+github\\.com\\/([^/]+)\\/?([^/]+)?/i)!\n return fetchSourceFactsFromGitHub(user, repo)\n\n /* GitLab repository */\n case \"gitlab\":\n const [, base, slug] = url.match(/^.+?([^/]*gitlab[^/]+)\\/(.+?)\\/?$/i)!\n return fetchSourceFactsFromGitLab(base, slug)\n\n /* Everything else */\n default:\n return EMPTY\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n catchError,\n defer,\n filter,\n finalize,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\nimport { renderSourceFacts } from \"~/templates\"\n\nimport { Component } from \"../../_\"\nimport {\n SourceFacts,\n fetchSourceFacts\n} from \"../facts\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information\n */\nexport interface Source {\n facts: SourceFacts /* Repository facts */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information observable\n */\nlet fetch$: Observable\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch repository information\n *\n * This function tries to read the repository facts from session storage, and\n * if unsuccessful, fetches them from the underlying provider.\n *\n * @param el - Repository information element\n *\n * @returns Repository information observable\n */\nexport function watchSource(\n el: HTMLAnchorElement\n): Observable {\n return fetch$ ||= defer(() => {\n const cached = __md_get(\"__source\", sessionStorage)\n if (cached)\n return of(cached)\n else\n return fetchSourceFacts(el.href)\n .pipe(\n tap(facts => __md_set(\"__source\", facts, sessionStorage))\n )\n })\n .pipe(\n catchError(() => EMPTY),\n filter(facts => Object.keys(facts).length > 0),\n map(facts => ({ facts })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount repository information\n *\n * @param el - Repository information element\n *\n * @returns Repository information component observable\n */\nexport function mountSource(\n el: HTMLAnchorElement\n): Observable> {\n const inner = getElement(\":scope > :last-child\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ facts }) => {\n inner.appendChild(renderSourceFacts(facts))\n inner.setAttribute(\"data-md-state\", \"done\")\n })\n\n /* Create and return component */\n return watchSource(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Navigation tabs\n */\nexport interface Tabs {\n hidden: boolean /* Navigation tabs are hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch navigation tabs\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs observable\n */\nexport function watchTabs(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchElementSize(document.body)\n .pipe(\n switchMap(() => watchViewportAt(el, { header$, viewport$ })),\n map(({ offset: { y } }) => {\n return {\n hidden: y >= 10\n }\n }),\n distinctUntilKeyChanged(\"hidden\")\n )\n}\n\n/**\n * Mount navigation tabs\n *\n * This function hides the navigation tabs when scrolling past the threshold\n * and makes them reappear in a nice CSS animation when scrolling back up.\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs component observable\n */\nexport function mountTabs(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n if (hidden)\n el.setAttribute(\"data-md-state\", \"hidden\")\n else\n el.removeAttribute(\"data-md-state\")\n },\n\n /* Handle complete */\n complete() {\n el.removeAttribute(\"data-md-state\")\n }\n })\n\n /* Create and return component */\n return (\n feature(\"navigation.tabs.sticky\")\n ? of({ hidden: false })\n : watchTabs(el, options)\n )\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatestWith,\n debounceTime,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n of,\n repeat,\n scan,\n share,\n skip,\n startWith,\n switchMap,\n takeLast,\n takeUntil,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n getElement,\n getElements,\n getLocation,\n getOptionalElement,\n watchElementSize\n} from \"~/browser\"\n\nimport {\n Component,\n getComponentElement\n} from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Table of contents\n */\nexport interface TableOfContents {\n prev: HTMLAnchorElement[][] /* Anchors (previous) */\n next: HTMLAnchorElement[][] /* Anchors (next) */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch table of contents\n *\n * This is effectively a scroll spy implementation which will account for the\n * fixed header and automatically re-calculate anchor offsets when the viewport\n * is resized. The returned observable will only emit if the table of contents\n * needs to be repainted.\n *\n * This implementation tracks an anchor element's entire path starting from its\n * level up to the top-most anchor element, e.g. `[h3, h2, h1]`. Although the\n * Material theme currently doesn't make use of this information, it enables\n * the styling of the entire hierarchy through customization.\n *\n * Note that the current anchor is the last item of the `prev` anchor list.\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents observable\n */\nexport function watchTableOfContents(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const table = new Map()\n\n /* Compute anchor-to-target mapping */\n const anchors = getElements(\"[href^=\\\\#]\", el)\n for (const anchor of anchors) {\n const id = decodeURIComponent(anchor.hash.substring(1))\n const target = getOptionalElement(`[id=\"${id}\"]`)\n if (typeof target !== \"undefined\")\n table.set(anchor, target)\n }\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n map(({ height }) => {\n const main = getComponentElement(\"main\")\n const grid = getElement(\":scope > :first-child\", main)\n return height + 0.8 * (\n grid.offsetTop -\n main.offsetTop\n )\n }),\n share()\n )\n\n /* Compute partition of previous and next anchors */\n const partition$ = watchElementSize(document.body)\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n\n /* Build index to map anchor paths to vertical offsets */\n switchMap(body => defer(() => {\n let path: HTMLAnchorElement[] = []\n return of([...table].reduce((index, [anchor, target]) => {\n while (path.length) {\n const last = table.get(path[path.length - 1])!\n if (last.tagName >= target.tagName) {\n path.pop()\n } else {\n break\n }\n }\n\n /* If the current anchor is hidden, continue with its parent */\n let offset = target.offsetTop\n while (!offset && target.parentElement) {\n target = target.parentElement\n offset = target.offsetTop\n }\n\n /* Map reversed anchor path to vertical offset */\n return index.set(\n [...path = [...path, anchor]].reverse(),\n offset\n )\n }, new Map()))\n })\n .pipe(\n\n /* Sort index by vertical offset (see https://bit.ly/30z6QSO) */\n map(index => new Map([...index].sort(([, a], [, b]) => a - b))),\n combineLatestWith(adjust$),\n\n /* Re-compute partition when viewport offset changes */\n switchMap(([index, adjust]) => viewport$\n .pipe(\n scan(([prev, next], { offset: { y }, size }) => {\n const last = y + size.height >= Math.floor(body.height)\n\n /* Look forward */\n while (next.length) {\n const [, offset] = next[0]\n if (offset - adjust < y || last) {\n prev = [...prev, next.shift()!]\n } else {\n break\n }\n }\n\n /* Look backward */\n while (prev.length) {\n const [, offset] = prev[prev.length - 1]\n if (offset - adjust >= y && !last) {\n next = [prev.pop()!, ...next]\n } else {\n break\n }\n }\n\n /* Return partition */\n return [prev, next]\n }, [[], [...index]]),\n distinctUntilChanged((a, b) => (\n a[0] === b[0] &&\n a[1] === b[1]\n ))\n )\n )\n )\n )\n )\n\n /* Compute and return anchor list migrations */\n return partition$\n .pipe(\n map(([prev, next]) => ({\n prev: prev.map(([path]) => path),\n next: next.map(([path]) => path)\n })),\n\n /* Extract anchor list migrations */\n startWith({ prev: [], next: [] }),\n bufferCount(2, 1),\n map(([a, b]) => {\n\n /* Moving down */\n if (a.prev.length < b.prev.length) {\n return {\n prev: b.prev.slice(Math.max(0, a.prev.length - 1), b.prev.length),\n next: []\n }\n\n /* Moving up */\n } else {\n return {\n prev: b.prev.slice(-1),\n next: b.next.slice(0, b.next.length - a.next.length)\n }\n }\n })\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount table of contents\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents component observable\n */\nexport function mountTableOfContents(\n el: HTMLElement, { viewport$, header$, target$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ prev, next }) => {\n\n /* Look forward */\n for (const [anchor] of next) {\n anchor.removeAttribute(\"data-md-state\")\n anchor.classList.remove(\n \"md-nav__link--active\"\n )\n }\n\n /* Look backward */\n for (const [index, [anchor]] of prev.entries()) {\n anchor.setAttribute(\"data-md-state\", \"blur\")\n anchor.classList.toggle(\n \"md-nav__link--active\",\n index === prev.length - 1\n )\n }\n })\n\n /* Set up anchor tracking, if enabled */\n if (feature(\"navigation.tracking\"))\n viewport$\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n distinctUntilKeyChanged(\"offset\"),\n debounceTime(250),\n skip(1),\n takeUntil(target$.pipe(skip(1))),\n repeat({ delay: 250 }),\n withLatestFrom(push$)\n )\n .subscribe(([, { prev }]) => {\n const url = getLocation()\n\n /* Set hash fragment to active anchor */\n const anchor = prev[prev.length - 1]\n if (anchor && anchor.length) {\n const [active] = anchor\n const { hash } = new URL(active.href)\n if (url.hash !== hash) {\n url.hash = hash\n history.replaceState({}, \"\", `${url}`)\n }\n\n /* Reset anchor when at the top */\n } else {\n url.hash = \"\"\n history.replaceState({}, \"\", `${url}`)\n }\n })\n\n /* Create and return component */\n return watchTableOfContents(el, { viewport$, header$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n endWith,\n finalize,\n map,\n repeat,\n skip,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { Viewport } from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Back-to-top button\n */\nexport interface BackToTop {\n hidden: boolean /* Back-to-top button is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch back-to-top\n *\n * @param _el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top observable\n */\nexport function watchBackToTop(\n _el: HTMLElement, { viewport$, main$, target$ }: WatchOptions\n): Observable {\n\n /* Compute direction */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => a > b && b > 0),\n distinctUntilChanged()\n )\n\n /* Compute whether main area is active */\n const active$ = main$\n .pipe(\n map(({ active }) => active)\n )\n\n /* Compute threshold for hiding */\n return combineLatest([active$, direction$])\n .pipe(\n map(([active, direction]) => !(active && direction)),\n distinctUntilChanged(),\n takeUntil(target$.pipe(skip(1))),\n endWith(true),\n repeat({ delay: 250 }),\n map(hidden => ({ hidden }))\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount back-to-top\n *\n * @param el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top component observable\n */\nexport function mountBackToTop(\n el: HTMLElement, { viewport$, header$, main$, target$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n if (hidden) {\n el.setAttribute(\"data-md-state\", \"hidden\")\n el.setAttribute(\"tabindex\", \"-1\")\n el.blur()\n } else {\n el.removeAttribute(\"data-md-state\")\n el.removeAttribute(\"tabindex\")\n }\n },\n\n /* Handle complete */\n complete() {\n el.style.top = \"\"\n el.setAttribute(\"data-md-state\", \"hidden\")\n el.removeAttribute(\"tabindex\")\n }\n })\n\n /* Watch header height */\n header$\n .pipe(\n takeUntil(push$.pipe(endWith(0), takeLast(1))),\n distinctUntilKeyChanged(\"height\")\n )\n .subscribe(({ height }) => {\n el.style.top = `${height + 16}px`\n })\n\n /* Create and return component */\n return watchBackToTop(el, { viewport$, main$, target$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n takeWhile,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch indeterminate checkboxes\n *\n * This function replaces the indeterminate \"pseudo state\" with the actual\n * indeterminate state, which is used to keep navigation always expanded.\n *\n * @param options - Options\n */\nexport function patchIndeterminate(\n { document$, tablet$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\n \"[data-md-state=indeterminate]\"\n )),\n tap(el => {\n el.indeterminate = true\n el.checked = false\n }),\n mergeMap(el => fromEvent(el, \"change\")\n .pipe(\n takeWhile(() => el.hasAttribute(\"data-md-state\")),\n map(() => el)\n )\n ),\n withLatestFrom(tablet$)\n )\n .subscribe(([el, tablet]) => {\n el.removeAttribute(\"data-md-state\")\n if (tablet)\n el.checked = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether the given device is an Apple device\n *\n * @returns Test result\n */\nfunction isAppleDevice(): boolean {\n return /(iPad|iPhone|iPod)/.test(navigator.userAgent)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all elements with `data-md-scrollfix` attributes\n *\n * This is a year-old patch which ensures that overflow scrolling works at the\n * top and bottom of containers on iOS by ensuring a `1px` scroll offset upon\n * the start of a touch event.\n *\n * @see https://bit.ly/2SCtAOO - Original source\n *\n * @param options - Options\n */\nexport function patchScrollfix(\n { document$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\"[data-md-scrollfix]\")),\n tap(el => el.removeAttribute(\"data-md-scrollfix\")),\n filter(isAppleDevice),\n mergeMap(el => fromEvent(el, \"touchstart\")\n .pipe(\n map(() => el)\n )\n )\n )\n .subscribe(el => {\n const top = el.scrollTop\n\n /* We're at the top of the container */\n if (top === 0) {\n el.scrollTop = 1\n\n /* We're at the bottom of the container */\n } else if (top + el.offsetHeight === el.scrollHeight) {\n el.scrollTop = top - 1\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n delay,\n map,\n of,\n switchMap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchToggle\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n viewport$: Observable /* Viewport observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch the document body to lock when search is open\n *\n * For mobile and tablet viewports, the search is rendered full screen, which\n * leads to scroll leaking when at the top or bottom of the search result. This\n * function locks the body when the search is in full screen mode, and restores\n * the scroll position when leaving.\n *\n * @param options - Options\n */\nexport function patchScrolllock(\n { viewport$, tablet$ }: PatchOptions\n): void {\n combineLatest([watchToggle(\"search\"), tablet$])\n .pipe(\n map(([active, tablet]) => active && !tablet),\n switchMap(active => of(active)\n .pipe(\n delay(active ? 400 : 100)\n )\n ),\n withLatestFrom(viewport$)\n )\n .subscribe(([active, { offset: { y }}]) => {\n if (active) {\n document.body.setAttribute(\"data-md-state\", \"lock\")\n document.body.style.top = `-${y}px`\n } else {\n const value = -1 * parseInt(document.body.style.top, 10)\n document.body.removeAttribute(\"data-md-state\")\n document.body.style.top = \"\"\n if (value)\n window.scrollTo(0, value)\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Polyfills\n * ------------------------------------------------------------------------- */\n\n/* Polyfill `Object.entries` */\nif (!Object.entries)\n Object.entries = function (obj: object) {\n const data: [string, string][] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push([key, obj[key]])\n\n /* Return entries */\n return data\n }\n\n/* Polyfill `Object.values` */\nif (!Object.values)\n Object.values = function (obj: object) {\n const data: string[] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push(obj[key])\n\n /* Return values */\n return data\n }\n\n/* ------------------------------------------------------------------------- */\n\n/* Polyfills for `Element` */\nif (typeof Element !== \"undefined\") {\n\n /* Polyfill `Element.scrollTo` */\n if (!Element.prototype.scrollTo)\n Element.prototype.scrollTo = function (\n x?: ScrollToOptions | number, y?: number\n ): void {\n if (typeof x === \"object\") {\n this.scrollLeft = x.left!\n this.scrollTop = x.top!\n } else {\n this.scrollLeft = x!\n this.scrollTop = y!\n }\n }\n\n /* Polyfill `Element.replaceWith` */\n if (!Element.prototype.replaceWith)\n Element.prototype.replaceWith = function (\n ...nodes: Array\n ): void {\n const parent = this.parentNode\n if (parent) {\n if (nodes.length === 0)\n parent.removeChild(this)\n\n /* Replace children and create text nodes */\n for (let i = nodes.length - 1; i >= 0; i--) {\n let node = nodes[i]\n if (typeof node !== \"object\")\n node = document.createTextNode(node)\n else if (node.parentNode)\n node.parentNode.removeChild(node)\n\n /* Replace child or insert before previous sibling */\n if (!i)\n parent.replaceChild(node, this)\n else\n parent.insertBefore(this.previousSibling!, node)\n }\n }\n }\n}\n"], - "mappings": "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", + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "(function(global) {\r\n /**\r\n * Polyfill URLSearchParams\r\n *\r\n * Inspired from : https://github.com/WebReflection/url-search-params/blob/master/src/url-search-params.js\r\n */\r\n\r\n var checkIfIteratorIsSupported = function() {\r\n try {\r\n return !!Symbol.iterator;\r\n } catch (error) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var iteratorSupported = checkIfIteratorIsSupported();\r\n\r\n var createIterator = function(items) {\r\n var iterator = {\r\n next: function() {\r\n var value = items.shift();\r\n return { done: value === void 0, value: value };\r\n }\r\n };\r\n\r\n if (iteratorSupported) {\r\n iterator[Symbol.iterator] = function() {\r\n return iterator;\r\n };\r\n }\r\n\r\n return iterator;\r\n };\r\n\r\n /**\r\n * Search param name and values should be encoded according to https://url.spec.whatwg.org/#urlencoded-serializing\r\n * encodeURIComponent() produces the same result except encoding spaces as `%20` instead of `+`.\r\n */\r\n var serializeParam = function(value) {\r\n return encodeURIComponent(value).replace(/%20/g, '+');\r\n };\r\n\r\n var deserializeParam = function(value) {\r\n return decodeURIComponent(String(value).replace(/\\+/g, ' '));\r\n };\r\n\r\n var polyfillURLSearchParams = function() {\r\n\r\n var URLSearchParams = function(searchString) {\r\n Object.defineProperty(this, '_entries', { writable: true, value: {} });\r\n var typeofSearchString = typeof searchString;\r\n\r\n if (typeofSearchString === 'undefined') {\r\n // do nothing\r\n } else if (typeofSearchString === 'string') {\r\n if (searchString !== '') {\r\n this._fromString(searchString);\r\n }\r\n } else if (searchString instanceof URLSearchParams) {\r\n var _this = this;\r\n searchString.forEach(function(value, name) {\r\n _this.append(name, value);\r\n });\r\n } else if ((searchString !== null) && (typeofSearchString === 'object')) {\r\n if (Object.prototype.toString.call(searchString) === '[object Array]') {\r\n for (var i = 0; i < searchString.length; i++) {\r\n var entry = searchString[i];\r\n if ((Object.prototype.toString.call(entry) === '[object Array]') || (entry.length !== 2)) {\r\n this.append(entry[0], entry[1]);\r\n } else {\r\n throw new TypeError('Expected [string, any] as entry at index ' + i + ' of URLSearchParams\\'s input');\r\n }\r\n }\r\n } else {\r\n for (var key in searchString) {\r\n if (searchString.hasOwnProperty(key)) {\r\n this.append(key, searchString[key]);\r\n }\r\n }\r\n }\r\n } else {\r\n throw new TypeError('Unsupported input\\'s type for URLSearchParams');\r\n }\r\n };\r\n\r\n var proto = URLSearchParams.prototype;\r\n\r\n proto.append = function(name, value) {\r\n if (name in this._entries) {\r\n this._entries[name].push(String(value));\r\n } else {\r\n this._entries[name] = [String(value)];\r\n }\r\n };\r\n\r\n proto.delete = function(name) {\r\n delete this._entries[name];\r\n };\r\n\r\n proto.get = function(name) {\r\n return (name in this._entries) ? this._entries[name][0] : null;\r\n };\r\n\r\n proto.getAll = function(name) {\r\n return (name in this._entries) ? this._entries[name].slice(0) : [];\r\n };\r\n\r\n proto.has = function(name) {\r\n return (name in this._entries);\r\n };\r\n\r\n proto.set = function(name, value) {\r\n this._entries[name] = [String(value)];\r\n };\r\n\r\n proto.forEach = function(callback, thisArg) {\r\n var entries;\r\n for (var name in this._entries) {\r\n if (this._entries.hasOwnProperty(name)) {\r\n entries = this._entries[name];\r\n for (var i = 0; i < entries.length; i++) {\r\n callback.call(thisArg, entries[i], name, this);\r\n }\r\n }\r\n }\r\n };\r\n\r\n proto.keys = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push(name);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.values = function() {\r\n var items = [];\r\n this.forEach(function(value) {\r\n items.push(value);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.entries = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n if (iteratorSupported) {\r\n proto[Symbol.iterator] = proto.entries;\r\n }\r\n\r\n proto.toString = function() {\r\n var searchArray = [];\r\n this.forEach(function(value, name) {\r\n searchArray.push(serializeParam(name) + '=' + serializeParam(value));\r\n });\r\n return searchArray.join('&');\r\n };\r\n\r\n\r\n global.URLSearchParams = URLSearchParams;\r\n };\r\n\r\n var checkIfURLSearchParamsSupported = function() {\r\n try {\r\n var URLSearchParams = global.URLSearchParams;\r\n\r\n return (\r\n (new URLSearchParams('?a=1').toString() === 'a=1') &&\r\n (typeof URLSearchParams.prototype.set === 'function') &&\r\n (typeof URLSearchParams.prototype.entries === 'function')\r\n );\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n if (!checkIfURLSearchParamsSupported()) {\r\n polyfillURLSearchParams();\r\n }\r\n\r\n var proto = global.URLSearchParams.prototype;\r\n\r\n if (typeof proto.sort !== 'function') {\r\n proto.sort = function() {\r\n var _this = this;\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n if (!_this._entries) {\r\n _this.delete(name);\r\n }\r\n });\r\n items.sort(function(a, b) {\r\n if (a[0] < b[0]) {\r\n return -1;\r\n } else if (a[0] > b[0]) {\r\n return +1;\r\n } else {\r\n return 0;\r\n }\r\n });\r\n if (_this._entries) { // force reset because IE keeps keys index\r\n _this._entries = {};\r\n }\r\n for (var i = 0; i < items.length; i++) {\r\n this.append(items[i][0], items[i][1]);\r\n }\r\n };\r\n }\r\n\r\n if (typeof proto._fromString !== 'function') {\r\n Object.defineProperty(proto, '_fromString', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function(searchString) {\r\n if (this._entries) {\r\n this._entries = {};\r\n } else {\r\n var keys = [];\r\n this.forEach(function(value, name) {\r\n keys.push(name);\r\n });\r\n for (var i = 0; i < keys.length; i++) {\r\n this.delete(keys[i]);\r\n }\r\n }\r\n\r\n searchString = searchString.replace(/^\\?/, '');\r\n var attributes = searchString.split('&');\r\n var attribute;\r\n for (var i = 0; i < attributes.length; i++) {\r\n attribute = attributes[i].split('=');\r\n this.append(\r\n deserializeParam(attribute[0]),\r\n (attribute.length > 1) ? deserializeParam(attribute[1]) : ''\r\n );\r\n }\r\n }\r\n });\r\n }\r\n\r\n // HTMLAnchorElement\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n\r\n(function(global) {\r\n /**\r\n * Polyfill URL\r\n *\r\n * Inspired from : https://github.com/arv/DOM-URL-Polyfill/blob/master/src/url.js\r\n */\r\n\r\n var checkIfURLIsSupported = function() {\r\n try {\r\n var u = new global.URL('b', 'http://a');\r\n u.pathname = 'c d';\r\n return (u.href === 'http://a/c%20d') && u.searchParams;\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var polyfillURL = function() {\r\n var _URL = global.URL;\r\n\r\n var URL = function(url, base) {\r\n if (typeof url !== 'string') url = String(url);\r\n if (base && typeof base !== 'string') base = String(base);\r\n\r\n // Only create another document if the base is different from current location.\r\n var doc = document, baseElement;\r\n if (base && (global.location === void 0 || base !== global.location.href)) {\r\n base = base.toLowerCase();\r\n doc = document.implementation.createHTMLDocument('');\r\n baseElement = doc.createElement('base');\r\n baseElement.href = base;\r\n doc.head.appendChild(baseElement);\r\n try {\r\n if (baseElement.href.indexOf(base) !== 0) throw new Error(baseElement.href);\r\n } catch (err) {\r\n throw new Error('URL unable to set base ' + base + ' due to ' + err);\r\n }\r\n }\r\n\r\n var anchorElement = doc.createElement('a');\r\n anchorElement.href = url;\r\n if (baseElement) {\r\n doc.body.appendChild(anchorElement);\r\n anchorElement.href = anchorElement.href; // force href to refresh\r\n }\r\n\r\n var inputElement = doc.createElement('input');\r\n inputElement.type = 'url';\r\n inputElement.value = url;\r\n\r\n if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href) || (!inputElement.checkValidity() && !base)) {\r\n throw new TypeError('Invalid URL');\r\n }\r\n\r\n Object.defineProperty(this, '_anchorElement', {\r\n value: anchorElement\r\n });\r\n\r\n\r\n // create a linked searchParams which reflect its changes on URL\r\n var searchParams = new global.URLSearchParams(this.search);\r\n var enableSearchUpdate = true;\r\n var enableSearchParamsUpdate = true;\r\n var _this = this;\r\n ['append', 'delete', 'set'].forEach(function(methodName) {\r\n var method = searchParams[methodName];\r\n searchParams[methodName] = function() {\r\n method.apply(searchParams, arguments);\r\n if (enableSearchUpdate) {\r\n enableSearchParamsUpdate = false;\r\n _this.search = searchParams.toString();\r\n enableSearchParamsUpdate = true;\r\n }\r\n };\r\n });\r\n\r\n Object.defineProperty(this, 'searchParams', {\r\n value: searchParams,\r\n enumerable: true\r\n });\r\n\r\n var search = void 0;\r\n Object.defineProperty(this, '_updateSearchParams', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function() {\r\n if (this.search !== search) {\r\n search = this.search;\r\n if (enableSearchParamsUpdate) {\r\n enableSearchUpdate = false;\r\n this.searchParams._fromString(this.search);\r\n enableSearchUpdate = true;\r\n }\r\n }\r\n }\r\n });\r\n };\r\n\r\n var proto = URL.prototype;\r\n\r\n var linkURLWithAnchorAttribute = function(attributeName) {\r\n Object.defineProperty(proto, attributeName, {\r\n get: function() {\r\n return this._anchorElement[attributeName];\r\n },\r\n set: function(value) {\r\n this._anchorElement[attributeName] = value;\r\n },\r\n enumerable: true\r\n });\r\n };\r\n\r\n ['hash', 'host', 'hostname', 'port', 'protocol']\r\n .forEach(function(attributeName) {\r\n linkURLWithAnchorAttribute(attributeName);\r\n });\r\n\r\n Object.defineProperty(proto, 'search', {\r\n get: function() {\r\n return this._anchorElement['search'];\r\n },\r\n set: function(value) {\r\n this._anchorElement['search'] = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n });\r\n\r\n Object.defineProperties(proto, {\r\n\r\n 'toString': {\r\n get: function() {\r\n var _this = this;\r\n return function() {\r\n return _this.href;\r\n };\r\n }\r\n },\r\n\r\n 'href': {\r\n get: function() {\r\n return this._anchorElement.href.replace(/\\?$/, '');\r\n },\r\n set: function(value) {\r\n this._anchorElement.href = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'pathname': {\r\n get: function() {\r\n return this._anchorElement.pathname.replace(/(^\\/?)/, '/');\r\n },\r\n set: function(value) {\r\n this._anchorElement.pathname = value;\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'origin': {\r\n get: function() {\r\n // get expected port from protocol\r\n var expectedPort = { 'http:': 80, 'https:': 443, 'ftp:': 21 }[this._anchorElement.protocol];\r\n // add port to origin if, expected port is different than actual port\r\n // and it is not empty f.e http://foo:8080\r\n // 8080 != 80 && 8080 != ''\r\n var addPortToOrigin = this._anchorElement.port != expectedPort &&\r\n this._anchorElement.port !== '';\r\n\r\n return this._anchorElement.protocol +\r\n '//' +\r\n this._anchorElement.hostname +\r\n (addPortToOrigin ? (':' + this._anchorElement.port) : '');\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'password': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'username': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n });\r\n\r\n URL.createObjectURL = function(blob) {\r\n return _URL.createObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n URL.revokeObjectURL = function(url) {\r\n return _URL.revokeObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n global.URL = URL;\r\n\r\n };\r\n\r\n if (!checkIfURLIsSupported()) {\r\n polyfillURL();\r\n }\r\n\r\n if ((global.location !== void 0) && !('origin' in global.location)) {\r\n var getOrigin = function() {\r\n return global.location.protocol + '//' + global.location.hostname + (global.location.port ? (':' + global.location.port) : '');\r\n };\r\n\r\n try {\r\n Object.defineProperty(global.location, 'origin', {\r\n get: getOrigin,\r\n enumerable: true\r\n });\r\n } catch (e) {\r\n setInterval(function() {\r\n global.location.origin = getOrigin();\r\n }, 100);\r\n }\r\n }\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global global, define, System, Reflect, Promise */\r\nvar __extends;\r\nvar __assign;\r\nvar __rest;\r\nvar __decorate;\r\nvar __param;\r\nvar __metadata;\r\nvar __awaiter;\r\nvar __generator;\r\nvar __exportStar;\r\nvar __values;\r\nvar __read;\r\nvar __spread;\r\nvar __spreadArrays;\r\nvar __spreadArray;\r\nvar __await;\r\nvar __asyncGenerator;\r\nvar __asyncDelegator;\r\nvar __asyncValues;\r\nvar __makeTemplateObject;\r\nvar __importStar;\r\nvar __importDefault;\r\nvar __classPrivateFieldGet;\r\nvar __classPrivateFieldSet;\r\nvar __createBinding;\r\n(function (factory) {\r\n var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\r\n if (typeof define === \"function\" && define.amd) {\r\n define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\r\n }\r\n else if (typeof module === \"object\" && typeof module.exports === \"object\") {\r\n factory(createExporter(root, createExporter(module.exports)));\r\n }\r\n else {\r\n factory(createExporter(root));\r\n }\r\n function createExporter(exports, previous) {\r\n if (exports !== root) {\r\n if (typeof Object.create === \"function\") {\r\n Object.defineProperty(exports, \"__esModule\", { value: true });\r\n }\r\n else {\r\n exports.__esModule = true;\r\n }\r\n }\r\n return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\r\n }\r\n})\r\n(function (exporter) {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n\r\n __extends = function (d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n\r\n __assign = Object.assign || function (t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n\r\n __rest = function (s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n };\r\n\r\n __decorate = function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n __param = function (paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n };\r\n\r\n __metadata = function (metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n };\r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n __exportStar = function(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n };\r\n\r\n __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n }) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n });\r\n\r\n __values = function (o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n };\r\n\r\n __read = function (o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spread = function () {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spreadArrays = function () {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n };\r\n\r\n __spreadArray = function (to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n };\r\n\r\n __await = function (v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n };\r\n\r\n __asyncGenerator = function (thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n };\r\n\r\n __asyncDelegator = function (o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n };\r\n\r\n __asyncValues = function (o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n };\r\n\r\n __makeTemplateObject = function (cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n };\r\n\r\n var __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n }) : function(o, v) {\r\n o[\"default\"] = v;\r\n };\r\n\r\n __importStar = function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n };\r\n\r\n __importDefault = function (mod) {\r\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\r\n };\r\n\r\n __classPrivateFieldGet = function (receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n };\r\n\r\n __classPrivateFieldSet = function (receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n };\r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n exporter(\"__rest\", __rest);\r\n exporter(\"__decorate\", __decorate);\r\n exporter(\"__param\", __param);\r\n exporter(\"__metadata\", __metadata);\r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n exporter(\"__exportStar\", __exportStar);\r\n exporter(\"__createBinding\", __createBinding);\r\n exporter(\"__values\", __values);\r\n exporter(\"__read\", __read);\r\n exporter(\"__spread\", __spread);\r\n exporter(\"__spreadArrays\", __spreadArrays);\r\n exporter(\"__spreadArray\", __spreadArray);\r\n exporter(\"__await\", __await);\r\n exporter(\"__asyncGenerator\", __asyncGenerator);\r\n exporter(\"__asyncDelegator\", __asyncDelegator);\r\n exporter(\"__asyncValues\", __asyncValues);\r\n exporter(\"__makeTemplateObject\", __makeTemplateObject);\r\n exporter(\"__importStar\", __importStar);\r\n exporter(\"__importDefault\", __importDefault);\r\n exporter(\"__classPrivateFieldGet\", __classPrivateFieldGet);\r\n exporter(\"__classPrivateFieldSet\", __classPrivateFieldSet);\r\n});\r\n", "/*!\n * clipboard.js v2.0.10\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n var fakeElement = createFakeElement(target);\n options.container.appendChild(fakeElement);\n selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n document.activeElement.blur();\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "Array.prototype.flat||Object.defineProperty(Array.prototype,\"flat\",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,function(a,e){return Array.isArray(e)?a.push.apply(a,r.call(e,t-1)):a.push(e),a},[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.flatMap||Object.defineProperty(Array.prototype,\"flatMap\",{configurable:!0,value:function(r){return Array.prototype.map.apply(this,arguments).flat()},writable:!0})\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"array-flat-polyfill\"\nimport \"focus-visible\"\nimport \"unfetch/polyfill\"\nimport \"url-polyfill\"\n\nimport {\n EMPTY,\n NEVER,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getOptionalElement,\n requestJSON,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountBackToTop,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantLoading,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget()\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? __search?.index || requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up instant loading, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantLoading({ document$, location$, viewport$ })\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"[href][rel=prev]\")\n if (typeof prev !== \"undefined\")\n prev.click()\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"[href][rel=next]\")\n if (typeof next !== \"undefined\")\n next.click()\n break\n }\n })\n\n/* Set up patches */\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, { viewport$, header$, target$ })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.component$ = component$ /* Component observable */\n", "self.fetch||(self.fetch=function(e,n){return n=n||{},new Promise(function(t,s){var r=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(r.status/100|0),statusText:r.statusText,status:r.status,url:r.responseURL,text:function(){return Promise.resolve(r.responseText)},json:function(){return Promise.resolve(r.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([r.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var c in r.open(n.method||\"get\",e,!0),r.onload=function(){r.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm,function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+\",\"+t:t}),t(a())},r.onerror=s,r.withCredentials=\"include\"==n.credentials,n.headers)r.setRequestHeader(c,n.headers[c]);r.send(n.body||null)})});\n", "import tslib from '../tslib.js';\r\nconst {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n} = tslib;\r\nexport {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n};\r\n", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ReplaySubject,\n Subject,\n fromEvent\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch document\n *\n * Documents are implemented as subjects, so all downstream observables are\n * automatically updated when a new document is emitted.\n *\n * @returns Document subject\n */\nexport function watchDocument(): Subject {\n const document$ = new ReplaySubject(1)\n fromEvent(document, \"DOMContentLoaded\", { once: true })\n .subscribe(() => document$.next(document))\n\n /* Return document */\n return document$\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve all elements matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getElements(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T][]\n\nexport function getElements(\n selector: string, node?: ParentNode\n): T[]\n\nexport function getElements(\n selector: string, node: ParentNode = document\n): T[] {\n return Array.from(node.querySelectorAll(selector))\n}\n\n/**\n * Retrieve an element matching a query selector or throw a reference error\n *\n * Note that this function assumes that the element is present. If unsure if an\n * element is existent, use the `getOptionalElement` function instead.\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElement(\n selector: string, node?: ParentNode\n): T\n\nexport function getElement(\n selector: string, node: ParentNode = document\n): T {\n const el = getOptionalElement(selector, node)\n if (typeof el === \"undefined\")\n throw new ReferenceError(\n `Missing element: expected \"${selector}\" to be present`\n )\n\n /* Return element */\n return el\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Retrieve an optional element matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element or nothing\n */\nexport function getOptionalElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T] | undefined\n\nexport function getOptionalElement(\n selector: string, node?: ParentNode\n): T | undefined\n\nexport function getOptionalElement(\n selector: string, node: ParentNode = document\n): T | undefined {\n return node.querySelector(selector) || undefined\n}\n\n/**\n * Retrieve the currently active element\n *\n * @returns Element or nothing\n */\nexport function getActiveElement(): HTMLElement | undefined {\n return document.activeElement instanceof HTMLElement\n ? document.activeElement || undefined\n : undefined\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n debounceTime,\n distinctUntilChanged,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element focus\n *\n * Previously, this function used `focus` and `blur` events to determine whether\n * an element is focused, but this doesn't work if there are focusable elements\n * within the elements itself. A better solutions are `focusin` and `focusout`\n * events, which bubble up the tree and allow for more fine-grained control.\n *\n * `debounceTime` is necessary, because when a focus change happens inside an\n * element, the observable would first emit `false` and then `true` again.\n *\n * @param el - Element\n *\n * @returns Element focus observable\n */\nexport function watchElementFocus(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(document.body, \"focusin\"),\n fromEvent(document.body, \"focusout\")\n )\n .pipe(\n debounceTime(1),\n map(() => {\n const active = getActiveElement()\n return typeof active !== \"undefined\"\n ? el.contains(active)\n : false\n }),\n startWith(el === getActiveElement()),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element offset\n *\n * @param el - Element\n *\n * @returns Element offset\n */\nexport function getElementOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.offsetLeft,\n y: el.offsetTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element offset\n *\n * @param el - Element\n *\n * @returns Element offset observable\n */\nexport function watchElementOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(window, \"load\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementOffset(el)),\n startWith(getElementOffset(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { ElementOffset } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content offset (= scroll offset)\n *\n * @param el - Element\n *\n * @returns Element content offset\n */\nexport function getElementContentOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.scrollLeft,\n y: el.scrollTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element content offset\n *\n * @param el - Element\n *\n * @returns Element content offset observable\n */\nexport function watchElementContentOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(el, \"scroll\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementContentOffset(el)),\n startWith(getElementContentOffset(el))\n )\n}\n", "/**\r\n * A collection of shims that provide minimal functionality of the ES6 collections.\r\n *\r\n * These implementations are not meant to be used outside of the ResizeObserver\r\n * modules as they cover only a limited range of use cases.\r\n */\r\n/* eslint-disable require-jsdoc, valid-jsdoc */\r\nvar MapShim = (function () {\r\n if (typeof Map !== 'undefined') {\r\n return Map;\r\n }\r\n /**\r\n * Returns index in provided array that matches the specified key.\r\n *\r\n * @param {Array} arr\r\n * @param {*} key\r\n * @returns {number}\r\n */\r\n function getIndex(arr, key) {\r\n var result = -1;\r\n arr.some(function (entry, index) {\r\n if (entry[0] === key) {\r\n result = index;\r\n return true;\r\n }\r\n return false;\r\n });\r\n return result;\r\n }\r\n return /** @class */ (function () {\r\n function class_1() {\r\n this.__entries__ = [];\r\n }\r\n Object.defineProperty(class_1.prototype, \"size\", {\r\n /**\r\n * @returns {boolean}\r\n */\r\n get: function () {\r\n return this.__entries__.length;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {*} key\r\n * @returns {*}\r\n */\r\n class_1.prototype.get = function (key) {\r\n var index = getIndex(this.__entries__, key);\r\n var entry = this.__entries__[index];\r\n return entry && entry[1];\r\n };\r\n /**\r\n * @param {*} key\r\n * @param {*} value\r\n * @returns {void}\r\n */\r\n class_1.prototype.set = function (key, value) {\r\n var index = getIndex(this.__entries__, key);\r\n if (~index) {\r\n this.__entries__[index][1] = value;\r\n }\r\n else {\r\n this.__entries__.push([key, value]);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.delete = function (key) {\r\n var entries = this.__entries__;\r\n var index = getIndex(entries, key);\r\n if (~index) {\r\n entries.splice(index, 1);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.has = function (key) {\r\n return !!~getIndex(this.__entries__, key);\r\n };\r\n /**\r\n * @returns {void}\r\n */\r\n class_1.prototype.clear = function () {\r\n this.__entries__.splice(0);\r\n };\r\n /**\r\n * @param {Function} callback\r\n * @param {*} [ctx=null]\r\n * @returns {void}\r\n */\r\n class_1.prototype.forEach = function (callback, ctx) {\r\n if (ctx === void 0) { ctx = null; }\r\n for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {\r\n var entry = _a[_i];\r\n callback.call(ctx, entry[1], entry[0]);\r\n }\r\n };\r\n return class_1;\r\n }());\r\n})();\n\n/**\r\n * Detects whether window and document objects are available in current environment.\r\n */\r\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;\n\n// Returns global object of a current environment.\r\nvar global$1 = (function () {\r\n if (typeof global !== 'undefined' && global.Math === Math) {\r\n return global;\r\n }\r\n if (typeof self !== 'undefined' && self.Math === Math) {\r\n return self;\r\n }\r\n if (typeof window !== 'undefined' && window.Math === Math) {\r\n return window;\r\n }\r\n // eslint-disable-next-line no-new-func\r\n return Function('return this')();\r\n})();\n\n/**\r\n * A shim for the requestAnimationFrame which falls back to the setTimeout if\r\n * first one is not supported.\r\n *\r\n * @returns {number} Requests' identifier.\r\n */\r\nvar requestAnimationFrame$1 = (function () {\r\n if (typeof requestAnimationFrame === 'function') {\r\n // It's required to use a bounded function because IE sometimes throws\r\n // an \"Invalid calling object\" error if rAF is invoked without the global\r\n // object on the left hand side.\r\n return requestAnimationFrame.bind(global$1);\r\n }\r\n return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };\r\n})();\n\n// Defines minimum timeout before adding a trailing call.\r\nvar trailingTimeout = 2;\r\n/**\r\n * Creates a wrapper function which ensures that provided callback will be\r\n * invoked only once during the specified delay period.\r\n *\r\n * @param {Function} callback - Function to be invoked after the delay period.\r\n * @param {number} delay - Delay after which to invoke callback.\r\n * @returns {Function}\r\n */\r\nfunction throttle (callback, delay) {\r\n var leadingCall = false, trailingCall = false, lastCallTime = 0;\r\n /**\r\n * Invokes the original callback function and schedules new invocation if\r\n * the \"proxy\" was called during current request.\r\n *\r\n * @returns {void}\r\n */\r\n function resolvePending() {\r\n if (leadingCall) {\r\n leadingCall = false;\r\n callback();\r\n }\r\n if (trailingCall) {\r\n proxy();\r\n }\r\n }\r\n /**\r\n * Callback invoked after the specified delay. It will further postpone\r\n * invocation of the original function delegating it to the\r\n * requestAnimationFrame.\r\n *\r\n * @returns {void}\r\n */\r\n function timeoutCallback() {\r\n requestAnimationFrame$1(resolvePending);\r\n }\r\n /**\r\n * Schedules invocation of the original function.\r\n *\r\n * @returns {void}\r\n */\r\n function proxy() {\r\n var timeStamp = Date.now();\r\n if (leadingCall) {\r\n // Reject immediately following calls.\r\n if (timeStamp - lastCallTime < trailingTimeout) {\r\n return;\r\n }\r\n // Schedule new call to be in invoked when the pending one is resolved.\r\n // This is important for \"transitions\" which never actually start\r\n // immediately so there is a chance that we might miss one if change\r\n // happens amids the pending invocation.\r\n trailingCall = true;\r\n }\r\n else {\r\n leadingCall = true;\r\n trailingCall = false;\r\n setTimeout(timeoutCallback, delay);\r\n }\r\n lastCallTime = timeStamp;\r\n }\r\n return proxy;\r\n}\n\n// Minimum delay before invoking the update of observers.\r\nvar REFRESH_DELAY = 20;\r\n// A list of substrings of CSS properties used to find transition events that\r\n// might affect dimensions of observed elements.\r\nvar transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];\r\n// Check if MutationObserver is available.\r\nvar mutationObserverSupported = typeof MutationObserver !== 'undefined';\r\n/**\r\n * Singleton controller class which handles updates of ResizeObserver instances.\r\n */\r\nvar ResizeObserverController = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserverController.\r\n *\r\n * @private\r\n */\r\n function ResizeObserverController() {\r\n /**\r\n * Indicates whether DOM listeners have been added.\r\n *\r\n * @private {boolean}\r\n */\r\n this.connected_ = false;\r\n /**\r\n * Tells that controller has subscribed for Mutation Events.\r\n *\r\n * @private {boolean}\r\n */\r\n this.mutationEventsAdded_ = false;\r\n /**\r\n * Keeps reference to the instance of MutationObserver.\r\n *\r\n * @private {MutationObserver}\r\n */\r\n this.mutationsObserver_ = null;\r\n /**\r\n * A list of connected observers.\r\n *\r\n * @private {Array}\r\n */\r\n this.observers_ = [];\r\n this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);\r\n this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);\r\n }\r\n /**\r\n * Adds observer to observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be added.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.addObserver = function (observer) {\r\n if (!~this.observers_.indexOf(observer)) {\r\n this.observers_.push(observer);\r\n }\r\n // Add listeners if they haven't been added yet.\r\n if (!this.connected_) {\r\n this.connect_();\r\n }\r\n };\r\n /**\r\n * Removes observer from observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be removed.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.removeObserver = function (observer) {\r\n var observers = this.observers_;\r\n var index = observers.indexOf(observer);\r\n // Remove observer if it's present in registry.\r\n if (~index) {\r\n observers.splice(index, 1);\r\n }\r\n // Remove listeners if controller has no connected observers.\r\n if (!observers.length && this.connected_) {\r\n this.disconnect_();\r\n }\r\n };\r\n /**\r\n * Invokes the update of observers. It will continue running updates insofar\r\n * it detects changes.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.refresh = function () {\r\n var changesDetected = this.updateObservers_();\r\n // Continue running updates if changes have been detected as there might\r\n // be future ones caused by CSS transitions.\r\n if (changesDetected) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Updates every observer from observers list and notifies them of queued\r\n * entries.\r\n *\r\n * @private\r\n * @returns {boolean} Returns \"true\" if any observer has detected changes in\r\n * dimensions of it's elements.\r\n */\r\n ResizeObserverController.prototype.updateObservers_ = function () {\r\n // Collect observers that have active observations.\r\n var activeObservers = this.observers_.filter(function (observer) {\r\n return observer.gatherActive(), observer.hasActive();\r\n });\r\n // Deliver notifications in a separate cycle in order to avoid any\r\n // collisions between observers, e.g. when multiple instances of\r\n // ResizeObserver are tracking the same element and the callback of one\r\n // of them changes content dimensions of the observed target. Sometimes\r\n // this may result in notifications being blocked for the rest of observers.\r\n activeObservers.forEach(function (observer) { return observer.broadcastActive(); });\r\n return activeObservers.length > 0;\r\n };\r\n /**\r\n * Initializes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.connect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already added.\r\n if (!isBrowser || this.connected_) {\r\n return;\r\n }\r\n // Subscription to the \"Transitionend\" event is used as a workaround for\r\n // delayed transitions. This way it's possible to capture at least the\r\n // final state of an element.\r\n document.addEventListener('transitionend', this.onTransitionEnd_);\r\n window.addEventListener('resize', this.refresh);\r\n if (mutationObserverSupported) {\r\n this.mutationsObserver_ = new MutationObserver(this.refresh);\r\n this.mutationsObserver_.observe(document, {\r\n attributes: true,\r\n childList: true,\r\n characterData: true,\r\n subtree: true\r\n });\r\n }\r\n else {\r\n document.addEventListener('DOMSubtreeModified', this.refresh);\r\n this.mutationEventsAdded_ = true;\r\n }\r\n this.connected_ = true;\r\n };\r\n /**\r\n * Removes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.disconnect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already removed.\r\n if (!isBrowser || !this.connected_) {\r\n return;\r\n }\r\n document.removeEventListener('transitionend', this.onTransitionEnd_);\r\n window.removeEventListener('resize', this.refresh);\r\n if (this.mutationsObserver_) {\r\n this.mutationsObserver_.disconnect();\r\n }\r\n if (this.mutationEventsAdded_) {\r\n document.removeEventListener('DOMSubtreeModified', this.refresh);\r\n }\r\n this.mutationsObserver_ = null;\r\n this.mutationEventsAdded_ = false;\r\n this.connected_ = false;\r\n };\r\n /**\r\n * \"Transitionend\" event handler.\r\n *\r\n * @private\r\n * @param {TransitionEvent} event\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {\r\n var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;\r\n // Detect whether transition may affect dimensions of an element.\r\n var isReflowProperty = transitionKeys.some(function (key) {\r\n return !!~propertyName.indexOf(key);\r\n });\r\n if (isReflowProperty) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Returns instance of the ResizeObserverController.\r\n *\r\n * @returns {ResizeObserverController}\r\n */\r\n ResizeObserverController.getInstance = function () {\r\n if (!this.instance_) {\r\n this.instance_ = new ResizeObserverController();\r\n }\r\n return this.instance_;\r\n };\r\n /**\r\n * Holds reference to the controller's instance.\r\n *\r\n * @private {ResizeObserverController}\r\n */\r\n ResizeObserverController.instance_ = null;\r\n return ResizeObserverController;\r\n}());\n\n/**\r\n * Defines non-writable/enumerable properties of the provided target object.\r\n *\r\n * @param {Object} target - Object for which to define properties.\r\n * @param {Object} props - Properties to be defined.\r\n * @returns {Object} Target object.\r\n */\r\nvar defineConfigurable = (function (target, props) {\r\n for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {\r\n var key = _a[_i];\r\n Object.defineProperty(target, key, {\r\n value: props[key],\r\n enumerable: false,\r\n writable: false,\r\n configurable: true\r\n });\r\n }\r\n return target;\r\n});\n\n/**\r\n * Returns the global object associated with provided element.\r\n *\r\n * @param {Object} target\r\n * @returns {Object}\r\n */\r\nvar getWindowOf = (function (target) {\r\n // Assume that the element is an instance of Node, which means that it\r\n // has the \"ownerDocument\" property from which we can retrieve a\r\n // corresponding global object.\r\n var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;\r\n // Return the local global object if it's not possible extract one from\r\n // provided element.\r\n return ownerGlobal || global$1;\r\n});\n\n// Placeholder of an empty content rectangle.\r\nvar emptyRect = createRectInit(0, 0, 0, 0);\r\n/**\r\n * Converts provided string to a number.\r\n *\r\n * @param {number|string} value\r\n * @returns {number}\r\n */\r\nfunction toFloat(value) {\r\n return parseFloat(value) || 0;\r\n}\r\n/**\r\n * Extracts borders size from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @param {...string} positions - Borders positions (top, right, ...)\r\n * @returns {number}\r\n */\r\nfunction getBordersSize(styles) {\r\n var positions = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n positions[_i - 1] = arguments[_i];\r\n }\r\n return positions.reduce(function (size, position) {\r\n var value = styles['border-' + position + '-width'];\r\n return size + toFloat(value);\r\n }, 0);\r\n}\r\n/**\r\n * Extracts paddings sizes from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @returns {Object} Paddings box.\r\n */\r\nfunction getPaddings(styles) {\r\n var positions = ['top', 'right', 'bottom', 'left'];\r\n var paddings = {};\r\n for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {\r\n var position = positions_1[_i];\r\n var value = styles['padding-' + position];\r\n paddings[position] = toFloat(value);\r\n }\r\n return paddings;\r\n}\r\n/**\r\n * Calculates content rectangle of provided SVG element.\r\n *\r\n * @param {SVGGraphicsElement} target - Element content rectangle of which needs\r\n * to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getSVGContentRect(target) {\r\n var bbox = target.getBBox();\r\n return createRectInit(0, 0, bbox.width, bbox.height);\r\n}\r\n/**\r\n * Calculates content rectangle of provided HTMLElement.\r\n *\r\n * @param {HTMLElement} target - Element for which to calculate the content rectangle.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getHTMLElementContentRect(target) {\r\n // Client width & height properties can't be\r\n // used exclusively as they provide rounded values.\r\n var clientWidth = target.clientWidth, clientHeight = target.clientHeight;\r\n // By this condition we can catch all non-replaced inline, hidden and\r\n // detached elements. Though elements with width & height properties less\r\n // than 0.5 will be discarded as well.\r\n //\r\n // Without it we would need to implement separate methods for each of\r\n // those cases and it's not possible to perform a precise and performance\r\n // effective test for hidden elements. E.g. even jQuery's ':visible' filter\r\n // gives wrong results for elements with width & height less than 0.5.\r\n if (!clientWidth && !clientHeight) {\r\n return emptyRect;\r\n }\r\n var styles = getWindowOf(target).getComputedStyle(target);\r\n var paddings = getPaddings(styles);\r\n var horizPad = paddings.left + paddings.right;\r\n var vertPad = paddings.top + paddings.bottom;\r\n // Computed styles of width & height are being used because they are the\r\n // only dimensions available to JS that contain non-rounded values. It could\r\n // be possible to utilize the getBoundingClientRect if only it's data wasn't\r\n // affected by CSS transformations let alone paddings, borders and scroll bars.\r\n var width = toFloat(styles.width), height = toFloat(styles.height);\r\n // Width & height include paddings and borders when the 'border-box' box\r\n // model is applied (except for IE).\r\n if (styles.boxSizing === 'border-box') {\r\n // Following conditions are required to handle Internet Explorer which\r\n // doesn't include paddings and borders to computed CSS dimensions.\r\n //\r\n // We can say that if CSS dimensions + paddings are equal to the \"client\"\r\n // properties then it's either IE, and thus we don't need to subtract\r\n // anything, or an element merely doesn't have paddings/borders styles.\r\n if (Math.round(width + horizPad) !== clientWidth) {\r\n width -= getBordersSize(styles, 'left', 'right') + horizPad;\r\n }\r\n if (Math.round(height + vertPad) !== clientHeight) {\r\n height -= getBordersSize(styles, 'top', 'bottom') + vertPad;\r\n }\r\n }\r\n // Following steps can't be applied to the document's root element as its\r\n // client[Width/Height] properties represent viewport area of the window.\r\n // Besides, it's as well not necessary as the itself neither has\r\n // rendered scroll bars nor it can be clipped.\r\n if (!isDocumentElement(target)) {\r\n // In some browsers (only in Firefox, actually) CSS width & height\r\n // include scroll bars size which can be removed at this step as scroll\r\n // bars are the only difference between rounded dimensions + paddings\r\n // and \"client\" properties, though that is not always true in Chrome.\r\n var vertScrollbar = Math.round(width + horizPad) - clientWidth;\r\n var horizScrollbar = Math.round(height + vertPad) - clientHeight;\r\n // Chrome has a rather weird rounding of \"client\" properties.\r\n // E.g. for an element with content width of 314.2px it sometimes gives\r\n // the client width of 315px and for the width of 314.7px it may give\r\n // 314px. And it doesn't happen all the time. So just ignore this delta\r\n // as a non-relevant.\r\n if (Math.abs(vertScrollbar) !== 1) {\r\n width -= vertScrollbar;\r\n }\r\n if (Math.abs(horizScrollbar) !== 1) {\r\n height -= horizScrollbar;\r\n }\r\n }\r\n return createRectInit(paddings.left, paddings.top, width, height);\r\n}\r\n/**\r\n * Checks whether provided element is an instance of the SVGGraphicsElement.\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nvar isSVGGraphicsElement = (function () {\r\n // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement\r\n // interface.\r\n if (typeof SVGGraphicsElement !== 'undefined') {\r\n return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };\r\n }\r\n // If it's so, then check that element is at least an instance of the\r\n // SVGElement and that it has the \"getBBox\" method.\r\n // eslint-disable-next-line no-extra-parens\r\n return function (target) { return (target instanceof getWindowOf(target).SVGElement &&\r\n typeof target.getBBox === 'function'); };\r\n})();\r\n/**\r\n * Checks whether provided element is a document element ().\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nfunction isDocumentElement(target) {\r\n return target === getWindowOf(target).document.documentElement;\r\n}\r\n/**\r\n * Calculates an appropriate content rectangle for provided html or svg element.\r\n *\r\n * @param {Element} target - Element content rectangle of which needs to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getContentRect(target) {\r\n if (!isBrowser) {\r\n return emptyRect;\r\n }\r\n if (isSVGGraphicsElement(target)) {\r\n return getSVGContentRect(target);\r\n }\r\n return getHTMLElementContentRect(target);\r\n}\r\n/**\r\n * Creates rectangle with an interface of the DOMRectReadOnly.\r\n * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly\r\n *\r\n * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.\r\n * @returns {DOMRectReadOnly}\r\n */\r\nfunction createReadOnlyRect(_a) {\r\n var x = _a.x, y = _a.y, width = _a.width, height = _a.height;\r\n // If DOMRectReadOnly is available use it as a prototype for the rectangle.\r\n var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;\r\n var rect = Object.create(Constr.prototype);\r\n // Rectangle's properties are not writable and non-enumerable.\r\n defineConfigurable(rect, {\r\n x: x, y: y, width: width, height: height,\r\n top: y,\r\n right: x + width,\r\n bottom: height + y,\r\n left: x\r\n });\r\n return rect;\r\n}\r\n/**\r\n * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.\r\n * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit\r\n *\r\n * @param {number} x - X coordinate.\r\n * @param {number} y - Y coordinate.\r\n * @param {number} width - Rectangle's width.\r\n * @param {number} height - Rectangle's height.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction createRectInit(x, y, width, height) {\r\n return { x: x, y: y, width: width, height: height };\r\n}\n\n/**\r\n * Class that is responsible for computations of the content rectangle of\r\n * provided DOM element and for keeping track of it's changes.\r\n */\r\nvar ResizeObservation = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObservation.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n */\r\n function ResizeObservation(target) {\r\n /**\r\n * Broadcasted width of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastWidth = 0;\r\n /**\r\n * Broadcasted height of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastHeight = 0;\r\n /**\r\n * Reference to the last observed content rectangle.\r\n *\r\n * @private {DOMRectInit}\r\n */\r\n this.contentRect_ = createRectInit(0, 0, 0, 0);\r\n this.target = target;\r\n }\r\n /**\r\n * Updates content rectangle and tells whether it's width or height properties\r\n * have changed since the last broadcast.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObservation.prototype.isActive = function () {\r\n var rect = getContentRect(this.target);\r\n this.contentRect_ = rect;\r\n return (rect.width !== this.broadcastWidth ||\r\n rect.height !== this.broadcastHeight);\r\n };\r\n /**\r\n * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data\r\n * from the corresponding properties of the last observed content rectangle.\r\n *\r\n * @returns {DOMRectInit} Last observed content rectangle.\r\n */\r\n ResizeObservation.prototype.broadcastRect = function () {\r\n var rect = this.contentRect_;\r\n this.broadcastWidth = rect.width;\r\n this.broadcastHeight = rect.height;\r\n return rect;\r\n };\r\n return ResizeObservation;\r\n}());\n\nvar ResizeObserverEntry = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObserverEntry.\r\n *\r\n * @param {Element} target - Element that is being observed.\r\n * @param {DOMRectInit} rectInit - Data of the element's content rectangle.\r\n */\r\n function ResizeObserverEntry(target, rectInit) {\r\n var contentRect = createReadOnlyRect(rectInit);\r\n // According to the specification following properties are not writable\r\n // and are also not enumerable in the native implementation.\r\n //\r\n // Property accessors are not being used as they'd require to define a\r\n // private WeakMap storage which may cause memory leaks in browsers that\r\n // don't support this type of collections.\r\n defineConfigurable(this, { target: target, contentRect: contentRect });\r\n }\r\n return ResizeObserverEntry;\r\n}());\n\nvar ResizeObserverSPI = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback function that is invoked\r\n * when one of the observed elements changes it's content dimensions.\r\n * @param {ResizeObserverController} controller - Controller instance which\r\n * is responsible for the updates of observer.\r\n * @param {ResizeObserver} callbackCtx - Reference to the public\r\n * ResizeObserver instance which will be passed to callback function.\r\n */\r\n function ResizeObserverSPI(callback, controller, callbackCtx) {\r\n /**\r\n * Collection of resize observations that have detected changes in dimensions\r\n * of elements.\r\n *\r\n * @private {Array}\r\n */\r\n this.activeObservations_ = [];\r\n /**\r\n * Registry of the ResizeObservation instances.\r\n *\r\n * @private {Map}\r\n */\r\n this.observations_ = new MapShim();\r\n if (typeof callback !== 'function') {\r\n throw new TypeError('The callback provided as parameter 1 is not a function.');\r\n }\r\n this.callback_ = callback;\r\n this.controller_ = controller;\r\n this.callbackCtx_ = callbackCtx;\r\n }\r\n /**\r\n * Starts observing provided element.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.observe = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is already being observed.\r\n if (observations.has(target)) {\r\n return;\r\n }\r\n observations.set(target, new ResizeObservation(target));\r\n this.controller_.addObserver(this);\r\n // Force the update of observations.\r\n this.controller_.refresh();\r\n };\r\n /**\r\n * Stops observing provided element.\r\n *\r\n * @param {Element} target - Element to stop observing.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.unobserve = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is not being observed.\r\n if (!observations.has(target)) {\r\n return;\r\n }\r\n observations.delete(target);\r\n if (!observations.size) {\r\n this.controller_.removeObserver(this);\r\n }\r\n };\r\n /**\r\n * Stops observing all elements.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.disconnect = function () {\r\n this.clearActive();\r\n this.observations_.clear();\r\n this.controller_.removeObserver(this);\r\n };\r\n /**\r\n * Collects observation instances the associated element of which has changed\r\n * it's content rectangle.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.gatherActive = function () {\r\n var _this = this;\r\n this.clearActive();\r\n this.observations_.forEach(function (observation) {\r\n if (observation.isActive()) {\r\n _this.activeObservations_.push(observation);\r\n }\r\n });\r\n };\r\n /**\r\n * Invokes initial callback function with a list of ResizeObserverEntry\r\n * instances collected from active resize observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.broadcastActive = function () {\r\n // Do nothing if observer doesn't have active observations.\r\n if (!this.hasActive()) {\r\n return;\r\n }\r\n var ctx = this.callbackCtx_;\r\n // Create ResizeObserverEntry instance for every active observation.\r\n var entries = this.activeObservations_.map(function (observation) {\r\n return new ResizeObserverEntry(observation.target, observation.broadcastRect());\r\n });\r\n this.callback_.call(ctx, entries, ctx);\r\n this.clearActive();\r\n };\r\n /**\r\n * Clears the collection of active observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.clearActive = function () {\r\n this.activeObservations_.splice(0);\r\n };\r\n /**\r\n * Tells whether observer has active observations.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObserverSPI.prototype.hasActive = function () {\r\n return this.activeObservations_.length > 0;\r\n };\r\n return ResizeObserverSPI;\r\n}());\n\n// Registry of internal observers. If WeakMap is not available use current shim\r\n// for the Map collection as it has all required methods and because WeakMap\r\n// can't be fully polyfilled anyway.\r\nvar observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();\r\n/**\r\n * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation\r\n * exposing only those methods and properties that are defined in the spec.\r\n */\r\nvar ResizeObserver = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback that is invoked when\r\n * dimensions of the observed elements change.\r\n */\r\n function ResizeObserver(callback) {\r\n if (!(this instanceof ResizeObserver)) {\r\n throw new TypeError('Cannot call a class as a function.');\r\n }\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n var controller = ResizeObserverController.getInstance();\r\n var observer = new ResizeObserverSPI(callback, controller, this);\r\n observers.set(this, observer);\r\n }\r\n return ResizeObserver;\r\n}());\r\n// Expose public methods of ResizeObserver.\r\n[\r\n 'observe',\r\n 'unobserve',\r\n 'disconnect'\r\n].forEach(function (method) {\r\n ResizeObserver.prototype[method] = function () {\r\n var _a;\r\n return (_a = observers.get(this))[method].apply(_a, arguments);\r\n };\r\n});\n\nvar index = (function () {\r\n // Export existing implementation if available.\r\n if (typeof global$1.ResizeObserver !== 'undefined') {\r\n return global$1.ResizeObserver;\r\n }\r\n return ResizeObserver;\r\n})();\n\nexport default index;\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ResizeObserver from \"resize-observer-polyfill\"\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n startWith,\n switchMap,\n tap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementSize {\n width: number /* Element width */\n height: number /* Element height */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Resize observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Resize observer observable\n *\n * This observable will create a `ResizeObserver` on the first subscription\n * and will automatically terminate it when there are no more subscribers.\n * It's quite important to centralize observation in a single `ResizeObserver`,\n * as the performance difference can be quite dramatic, as the link shows.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new ResizeObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element size\n *\n * @param el - Element\n *\n * @returns Element size\n */\nexport function getElementSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.offsetWidth,\n height: el.offsetHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element size\n *\n * This function returns an observable that subscribes to a single internal\n * instance of `ResizeObserver` upon subscription, and emit resize events until\n * termination. Note that this function should not be called with the same\n * element twice, as the first unsubscription will terminate observation.\n *\n * Sadly, we can't use the `DOMRect` objects returned by the observer, because\n * we need the emitted values to be consistent with `getElementSize`, which will\n * return the used values (rounded) and not actual values (unrounded). Thus, we\n * use the `offset*` properties. See the linked GitHub issue.\n *\n * @see https://bit.ly/3m0k3he - GitHub issue\n *\n * @param el - Element\n *\n * @returns Element size observable\n */\nexport function watchElementSize(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(() => getElementSize(el))\n )\n ),\n startWith(getElementSize(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ElementSize } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content size (= scroll width and height)\n *\n * @param el - Element\n *\n * @returns Element content size\n */\nexport function getElementContentSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.scrollWidth,\n height: el.scrollHeight\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport {\n getElementContentSize,\n getElementSize,\n watchElementContentOffset\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Intersection observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Intersection observer observable\n *\n * This observable will create an `IntersectionObserver` on first subscription\n * and will automatically terminate it when there are no more subscribers.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new IntersectionObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n }, {\n threshold: 0\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element visibility\n *\n * @param el - Element\n *\n * @returns Element visibility observable\n */\nexport function watchElementVisibility(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(({ isIntersecting }) => isIntersecting)\n )\n )\n )\n}\n\n/**\n * Watch element boundary\n *\n * This function returns an observable which emits whether the bottom content\n * boundary (= scroll offset) of an element is within a certain threshold.\n *\n * @param el - Element\n * @param threshold - Threshold\n *\n * @returns Element boundary observable\n */\nexport function watchElementBoundary(\n el: HTMLElement, threshold = 16\n): Observable {\n return watchElementContentOffset(el)\n .pipe(\n map(({ y }) => {\n const visible = getElementSize(el)\n const content = getElementContentSize(el)\n return y >= (\n content.height - visible.height - threshold\n )\n }),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getElement } from \"../element\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle\n */\nexport type Toggle =\n | \"drawer\" /* Toggle for drawer */\n | \"search\" /* Toggle for search */\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle map\n */\nconst toggles: Record = {\n drawer: getElement(\"[data-md-toggle=drawer]\"),\n search: getElement(\"[data-md-toggle=search]\")\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the value of a toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value\n */\nexport function getToggle(name: Toggle): boolean {\n return toggles[name].checked\n}\n\n/**\n * Set toggle\n *\n * Simulating a click event seems to be the most cross-browser compatible way\n * of changing the value while also emitting a `change` event. Before, Material\n * used `CustomEvent` to programmatically change the value of a toggle, but this\n * is a much simpler and cleaner solution which doesn't require a polyfill.\n *\n * @param name - Toggle\n * @param value - Toggle value\n */\nexport function setToggle(name: Toggle, value: boolean): void {\n if (toggles[name].checked !== value)\n toggles[name].click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value observable\n */\nexport function watchToggle(name: Toggle): Observable {\n const el = toggles[name]\n return fromEvent(el, \"change\")\n .pipe(\n map(() => el.checked),\n startWith(el.checked)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n share\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../element\"\nimport { getToggle } from \"../toggle\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Keyboard mode\n */\nexport type KeyboardMode =\n | \"global\" /* Global */\n | \"search\" /* Search is open */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Keyboard\n */\nexport interface Keyboard {\n mode: KeyboardMode /* Keyboard mode */\n type: string /* Key type */\n claim(): void /* Key claim */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether an element may receive keyboard input\n *\n * @param el - Element\n * @param type - Key type\n *\n * @returns Test result\n */\nfunction isSusceptibleToKeyboard(\n el: HTMLElement, type: string\n): boolean {\n switch (el.constructor) {\n\n /* Input elements */\n case HTMLInputElement:\n /* @ts-expect-error - omit unnecessary type cast */\n if (el.type === \"radio\")\n return /^Arrow/.test(type)\n else\n return true\n\n /* Select element and textarea */\n case HTMLSelectElement:\n case HTMLTextAreaElement:\n return true\n\n /* Everything else */\n default:\n return el.isContentEditable\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch keyboard\n *\n * @returns Keyboard observable\n */\nexport function watchKeyboard(): Observable {\n return fromEvent(window, \"keydown\")\n .pipe(\n filter(ev => !(ev.metaKey || ev.ctrlKey)),\n map(ev => ({\n mode: getToggle(\"search\") ? \"search\" : \"global\",\n type: ev.key,\n claim() {\n ev.preventDefault()\n ev.stopPropagation()\n }\n } as Keyboard)),\n filter(({ mode, type }) => {\n if (mode === \"global\") {\n const active = getActiveElement()\n if (typeof active !== \"undefined\")\n return !isSusceptibleToKeyboard(active, type)\n }\n return true\n }),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Subject } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location\n *\n * This function returns a `URL` object (and not `Location`) to normalize the\n * typings across the application. Furthermore, locations need to be tracked\n * without setting them and `Location` is a singleton which represents the\n * current location.\n *\n * @returns URL\n */\nexport function getLocation(): URL {\n return new URL(location.href)\n}\n\n/**\n * Set location\n *\n * @param url - URL to change to\n */\nexport function setLocation(url: URL): void {\n location.href = url.href\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location\n *\n * @returns Location subject\n */\nexport function watchLocation(): Subject {\n return new Subject()\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { JSX as JSXInternal } from \"preact\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * HTML attributes\n */\ntype Attributes =\n & JSXInternal.HTMLAttributes\n & JSXInternal.SVGAttributes\n & Record\n\n/**\n * Child element\n */\ntype Child =\n | HTMLElement\n | Text\n | string\n | number\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Append a child node to an element\n *\n * @param el - Element\n * @param child - Child node(s)\n */\nfunction appendChild(el: HTMLElement, child: Child | Child[]): void {\n\n /* Handle primitive types (including raw HTML) */\n if (typeof child === \"string\" || typeof child === \"number\") {\n el.innerHTML += child.toString()\n\n /* Handle nodes */\n } else if (child instanceof Node) {\n el.appendChild(child)\n\n /* Handle nested children */\n } else if (Array.isArray(child)) {\n for (const node of child)\n appendChild(el, node)\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * JSX factory\n *\n * @template T - Element type\n *\n * @param tag - HTML tag\n * @param attributes - HTML attributes\n * @param children - Child elements\n *\n * @returns Element\n */\nexport function h(\n tag: T, attributes?: Attributes | null, ...children: Child[]\n): HTMLElementTagNameMap[T]\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T {\n const el = document.createElement(tag)\n\n /* Set attributes, if any */\n if (attributes)\n for (const attr of Object.keys(attributes))\n if (typeof attributes[attr] !== \"boolean\")\n el.setAttribute(attr, attributes[attr])\n else if (attributes[attr])\n el.setAttribute(attr, \"\")\n\n /* Append child nodes */\n for (const child of children)\n appendChild(el, child)\n\n /* Return element */\n return el as T\n}\n\n/* ----------------------------------------------------------------------------\n * Namespace\n * ------------------------------------------------------------------------- */\n\nexport declare namespace h {\n namespace JSX {\n type Element = HTMLElement\n type IntrinsicElements = JSXInternal.IntrinsicElements\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Truncate a string after the given number of characters\n *\n * This is not a very reasonable approach, since the summaries kind of suck.\n * It would be better to create something more intelligent, highlighting the\n * search occurrences and making a better summary out of it, but this note was\n * written three years ago, so who knows if we'll ever fix it.\n *\n * @param value - Value to be truncated\n * @param n - Number of characters\n *\n * @returns Truncated value\n */\nexport function truncate(value: string, n: number): string {\n let i = n\n if (value.length > i) {\n while (value[i] !== \" \" && --i > 0) { /* keep eating */ }\n return `${value.substring(0, i)}...`\n }\n return value\n}\n\n/**\n * Round a number for display with repository facts\n *\n * This is a reverse-engineered version of GitHub's weird rounding algorithm\n * for stars, forks and all other numbers. While all numbers below `1,000` are\n * returned as-is, bigger numbers are converted to fixed numbers:\n *\n * - `1,049` => `1k`\n * - `1,050` => `1.1k`\n * - `1,949` => `1.9k`\n * - `1,950` => `2k`\n *\n * @param value - Original value\n *\n * @returns Rounded value\n */\nexport function round(value: number): string {\n if (value > 999) {\n const digits = +((value - 950) % 1000 > 99)\n return `${((value + 0.000001) / 1000).toFixed(digits)}k`\n } else {\n return value.toString()\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n shareReplay,\n startWith\n} from \"rxjs\"\n\nimport { getOptionalElement } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location hash\n *\n * @returns Location hash\n */\nexport function getLocationHash(): string {\n return location.hash.substring(1)\n}\n\n/**\n * Set location hash\n *\n * Setting a new fragment identifier via `location.hash` will have no effect\n * if the value doesn't change. When a new fragment identifier is set, we want\n * the browser to target the respective element at all times, which is why we\n * use this dirty little trick.\n *\n * @param hash - Location hash\n */\nexport function setLocationHash(hash: string): void {\n const el = h(\"a\", { href: hash })\n el.addEventListener(\"click\", ev => ev.stopPropagation())\n el.click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location hash\n *\n * @returns Location hash observable\n */\nexport function watchLocationHash(): Observable {\n return fromEvent(window, \"hashchange\")\n .pipe(\n map(getLocationHash),\n startWith(getLocationHash()),\n filter(hash => hash.length > 0),\n shareReplay(1)\n )\n}\n\n/**\n * Watch location target\n *\n * @returns Location target observable\n */\nexport function watchLocationTarget(): Observable {\n return watchLocationHash()\n .pipe(\n map(id => getOptionalElement(`[id=\"${id}\"]`)!),\n filter(el => typeof el !== \"undefined\")\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n fromEvent,\n fromEventPattern,\n map,\n merge,\n startWith,\n switchMap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch media query\n *\n * Note that although `MediaQueryList.addListener` is deprecated we have to\n * use it, because it's the only way to ensure proper downward compatibility.\n *\n * @see https://bit.ly/3dUBH2m - GitHub issue\n *\n * @param query - Media query\n *\n * @returns Media observable\n */\nexport function watchMedia(query: string): Observable {\n const media = matchMedia(query)\n return fromEventPattern(next => (\n media.addListener(() => next(media.matches))\n ))\n .pipe(\n startWith(media.matches)\n )\n}\n\n/**\n * Watch print mode\n *\n * @returns Print observable\n */\nexport function watchPrint(): Observable {\n const media = matchMedia(\"print\")\n return merge(\n fromEvent(window, \"beforeprint\").pipe(map(() => true)),\n fromEvent(window, \"afterprint\").pipe(map(() => false))\n )\n .pipe(\n startWith(media.matches)\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Toggle an observable with a media observable\n *\n * @template T - Data type\n *\n * @param query$ - Media observable\n * @param factory - Observable factory\n *\n * @returns Toggled observable\n */\nexport function at(\n query$: Observable, factory: () => Observable\n): Observable {\n return query$\n .pipe(\n switchMap(active => active ? factory() : EMPTY)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n catchError,\n from,\n map,\n of,\n shareReplay,\n switchMap,\n throwError\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the given URL\n *\n * If the request fails (e.g. when dispatched from `file://` locations), the\n * observable will complete without emitting a value.\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Response observable\n */\nexport function request(\n url: URL | string, options: RequestInit = { credentials: \"same-origin\" }\n): Observable {\n return from(fetch(`${url}`, options))\n .pipe(\n catchError(() => EMPTY),\n switchMap(res => res.status !== 200\n ? throwError(() => new Error(res.statusText))\n : of(res)\n )\n )\n}\n\n/**\n * Fetch JSON from the given URL\n *\n * @template T - Data type\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestJSON(\n url: URL | string, options?: RequestInit\n): Observable {\n return request(url, options)\n .pipe(\n switchMap(res => res.json()),\n shareReplay(1)\n )\n}\n\n/**\n * Fetch XML from the given URL\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestXML(\n url: URL | string, options?: RequestInit\n): Observable {\n const dom = new DOMParser()\n return request(url, options)\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/xml\")),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n switchMap,\n take,\n throwError\n} from \"rxjs\"\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create and load a `script` element\n *\n * This function returns an observable that will emit when the script was\n * successfully loaded, or throw an error if it didn't.\n *\n * @param src - Script URL\n *\n * @returns Script observable\n */\nexport function watchScript(src: string): Observable {\n const script = h(\"script\", { src })\n return defer(() => {\n document.head.appendChild(script)\n return merge(\n fromEvent(script, \"load\"),\n fromEvent(script, \"error\")\n .pipe(\n switchMap(() => (\n throwError(() => new ReferenceError(`Invalid script: ${src}`))\n ))\n )\n )\n .pipe(\n map(() => undefined),\n finalize(() => document.head.removeChild(script)),\n take(1)\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport offset\n */\nexport interface ViewportOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport offset\n *\n * On iOS Safari, viewport offset can be negative due to overflow scrolling.\n * As this may induce strange behaviors downstream, we'll just limit it to 0.\n *\n * @returns Viewport offset\n */\nexport function getViewportOffset(): ViewportOffset {\n return {\n x: Math.max(0, scrollX),\n y: Math.max(0, scrollY)\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport offset\n *\n * @returns Viewport offset observable\n */\nexport function watchViewportOffset(): Observable {\n return merge(\n fromEvent(window, \"scroll\", { passive: true }),\n fromEvent(window, \"resize\", { passive: true })\n )\n .pipe(\n map(getViewportOffset),\n startWith(getViewportOffset())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport size\n */\nexport interface ViewportSize {\n width: number /* Viewport width */\n height: number /* Viewport height */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport size\n *\n * @returns Viewport size\n */\nexport function getViewportSize(): ViewportSize {\n return {\n width: innerWidth,\n height: innerHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport size\n *\n * @returns Viewport size observable\n */\nexport function watchViewportSize(): Observable {\n return fromEvent(window, \"resize\", { passive: true })\n .pipe(\n map(getViewportSize),\n startWith(getViewportSize())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n map,\n shareReplay\n} from \"rxjs\"\n\nimport {\n ViewportOffset,\n watchViewportOffset\n} from \"../offset\"\nimport {\n ViewportSize,\n watchViewportSize\n} from \"../size\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport\n */\nexport interface Viewport {\n offset: ViewportOffset /* Viewport offset */\n size: ViewportSize /* Viewport size */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport\n *\n * @returns Viewport observable\n */\nexport function watchViewport(): Observable {\n return combineLatest([\n watchViewportOffset(),\n watchViewportSize()\n ])\n .pipe(\n map(([offset, size]) => ({ offset, size })),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilKeyChanged,\n map\n} from \"rxjs\"\n\nimport { Header } from \"~/components\"\n\nimport { getElementOffset } from \"../../element\"\nimport { Viewport } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport relative to element\n *\n * @param el - Element\n * @param options - Options\n *\n * @returns Viewport observable\n */\nexport function watchViewportAt(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const size$ = viewport$\n .pipe(\n distinctUntilKeyChanged(\"size\")\n )\n\n /* Compute element offset */\n const offset$ = combineLatest([size$, header$])\n .pipe(\n map(() => getElementOffset(el))\n )\n\n /* Compute relative viewport, return hot observable */\n return combineLatest([header$, viewport$, offset$])\n .pipe(\n map(([{ height }, { offset, size }, { x, y }]) => ({\n offset: {\n x: offset.x - x,\n y: offset.y - y + height\n },\n size\n }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n fromEvent,\n map,\n share,\n switchMap,\n tap,\n throttle\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Worker message\n */\nexport interface WorkerMessage {\n type: unknown /* Message type */\n data?: unknown /* Message data */\n}\n\n/**\n * Worker handler\n *\n * @template T - Message type\n */\nexport interface WorkerHandler<\n T extends WorkerMessage\n> {\n tx$: Subject /* Message transmission subject */\n rx$: Observable /* Message receive observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n *\n * @template T - Worker message type\n */\ninterface WatchOptions {\n tx$: Observable /* Message transmission observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch a web worker\n *\n * This function returns an observable that sends all values emitted by the\n * message observable to the web worker. Web worker communication is expected\n * to be bidirectional (request-response) and synchronous. Messages that are\n * emitted during a pending request are throttled, the last one is emitted.\n *\n * @param worker - Web worker\n * @param options - Options\n *\n * @returns Worker message observable\n */\nexport function watchWorker(\n worker: Worker, { tx$ }: WatchOptions\n): Observable {\n\n /* Intercept messages from worker-like objects */\n const rx$ = fromEvent(worker, \"message\")\n .pipe(\n map(({ data }) => data as T)\n )\n\n /* Send and receive messages, return hot observable */\n return tx$\n .pipe(\n throttle(() => rx$, { leading: true, trailing: true }),\n tap(message => worker.postMessage(message)),\n switchMap(() => rx$),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getLocation } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flag\n */\nexport type Flag =\n | \"content.code.annotate\" /* Code annotations */\n | \"header.autohide\" /* Hide header */\n | \"navigation.expand\" /* Automatic expansion */\n | \"navigation.indexes\" /* Section pages */\n | \"navigation.instant\" /* Instant loading */\n | \"navigation.sections\" /* Section navigation */\n | \"navigation.tabs\" /* Tabs navigation */\n | \"navigation.tabs.sticky\" /* Tabs navigation (sticky) */\n | \"navigation.top\" /* Back-to-top button */\n | \"navigation.tracking\" /* Anchor tracking */\n | \"search.highlight\" /* Search highlighting */\n | \"search.share\" /* Search sharing */\n | \"search.suggest\" /* Search suggestions */\n | \"toc.integrate\" /* Integrated table of contents */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Translation\n */\nexport type Translation =\n | \"clipboard.copy\" /* Copy to clipboard */\n | \"clipboard.copied\" /* Copied to clipboard */\n | \"search.config.lang\" /* Search language */\n | \"search.config.pipeline\" /* Search pipeline */\n | \"search.config.separator\" /* Search separator */\n | \"search.placeholder\" /* Search */\n | \"search.result.placeholder\" /* Type to start searching */\n | \"search.result.none\" /* No matching documents */\n | \"search.result.one\" /* 1 matching document */\n | \"search.result.other\" /* # matching documents */\n | \"search.result.more.one\" /* 1 more on this page */\n | \"search.result.more.other\" /* # more on this page */\n | \"search.result.term.missing\" /* Missing */\n | \"select.version.title\" /* Version selector */\n\n/**\n * Translations\n */\nexport type Translations = Record\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Versioning\n */\nexport interface Versioning {\n provider: \"mike\" /* Version provider */\n default?: string /* Default version */\n}\n\n/**\n * Configuration\n */\nexport interface Config {\n base: string /* Base URL */\n features: Flag[] /* Feature flags */\n translations: Translations /* Translations */\n search: string /* Search worker URL */\n version?: Versioning /* Versioning */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration and make base URL absolute\n */\nconst script = getElement(\"#__config\")\nconst config: Config = JSON.parse(script.textContent!)\nconfig.base = `${new URL(config.base, getLocation())}`\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration\n *\n * @returns Global configuration\n */\nexport function configuration(): Config {\n return config\n}\n\n/**\n * Check whether a feature flag is enabled\n *\n * @param flag - Feature flag\n *\n * @returns Test result\n */\nexport function feature(flag: Flag): boolean {\n return config.features.includes(flag)\n}\n\n/**\n * Retrieve the translation for the given key\n *\n * @param key - Key to be translated\n * @param value - Positional value, if any\n *\n * @returns Translation\n */\nexport function translation(\n key: Translation, value?: string | number\n): string {\n return typeof value !== \"undefined\"\n ? config.translations[key].replace(\"#\", value.toString())\n : config.translations[key]\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type\n */\nexport type ComponentType =\n | \"announce\" /* Announcement bar */\n | \"container\" /* Container */\n | \"content\" /* Content */\n | \"dialog\" /* Dialog */\n | \"header\" /* Header */\n | \"header-title\" /* Header title */\n | \"header-topic\" /* Header topic */\n | \"main\" /* Main area */\n | \"outdated\" /* Version warning */\n | \"palette\" /* Color palette */\n | \"search\" /* Search */\n | \"search-query\" /* Search input */\n | \"search-result\" /* Search results */\n | \"search-share\" /* Search sharing */\n | \"search-suggest\" /* Search suggestions */\n | \"sidebar\" /* Sidebar */\n | \"skip\" /* Skip link */\n | \"source\" /* Repository information */\n | \"tabs\" /* Navigation tabs */\n | \"toc\" /* Table of contents */\n | \"top\" /* Back-to-top button */\n\n/**\n * Component\n *\n * @template T - Component type\n * @template U - Reference type\n */\nexport type Component<\n T extends {} = {},\n U extends HTMLElement = HTMLElement\n> =\n T & {\n ref: U /* Component reference */\n }\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type map\n */\ninterface ComponentTypeMap {\n \"announce\": HTMLElement /* Announcement bar */\n \"container\": HTMLElement /* Container */\n \"content\": HTMLElement /* Content */\n \"dialog\": HTMLElement /* Dialog */\n \"header\": HTMLElement /* Header */\n \"header-title\": HTMLElement /* Header title */\n \"header-topic\": HTMLElement /* Header topic */\n \"main\": HTMLElement /* Main area */\n \"outdated\": HTMLElement /* Version warning */\n \"palette\": HTMLElement /* Color palette */\n \"search\": HTMLElement /* Search */\n \"search-query\": HTMLInputElement /* Search input */\n \"search-result\": HTMLElement /* Search results */\n \"search-share\": HTMLAnchorElement /* Search sharing */\n \"search-suggest\": HTMLElement /* Search suggestions */\n \"sidebar\": HTMLElement /* Sidebar */\n \"skip\": HTMLAnchorElement /* Skip link */\n \"source\": HTMLAnchorElement /* Repository information */\n \"tabs\": HTMLElement /* Navigation tabs */\n \"toc\": HTMLElement /* Table of contents */\n \"top\": HTMLAnchorElement /* Back-to-top button */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the element for a given component or throw a reference error\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getComponentElement(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T] {\n return getElement(`[data-md-component=${type}]`, node)\n}\n\n/**\n * Retrieve all elements for a given component\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getComponentElements(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T][] {\n return getElements(`[data-md-component=${type}]`, node)\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n map,\n mergeWith,\n switchMap,\n take,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n getElementContentSize,\n watchElementSize,\n watchElementVisibility\n} from \"~/browser\"\nimport { renderClipboardButton } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotationList\n} from \"../../annotation\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Code block\n */\nexport interface CodeBlock {\n scrollable: boolean /* Code block overflows */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Global sequence number for Clipboard.js integration\n */\nlet sequence = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find candidate list element directly following a code block\n *\n * @param el - Code block element\n *\n * @returns List element or nothing\n */\nfunction findCandidateList(el: HTMLElement): HTMLElement | undefined {\n if (el.nextElementSibling) {\n const sibling = el.nextElementSibling as HTMLElement\n if (sibling.tagName === \"OL\")\n return sibling\n\n /* Skip empty paragraphs - see https://bit.ly/3r4ZJ2O */\n else if (sibling.tagName === \"P\" && !sibling.children.length)\n return findCandidateList(sibling)\n }\n\n /* Everything else */\n return undefined\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch code block\n *\n * This function monitors size changes of the viewport, as well as switches of\n * content tabs with embedded code blocks, as both may trigger overflow.\n *\n * @param el - Code block element\n *\n * @returns Code block observable\n */\nexport function watchCodeBlock(\n el: HTMLElement\n): Observable {\n return watchElementSize(el)\n .pipe(\n map(({ width }) => {\n const content = getElementContentSize(el)\n return {\n scrollable: content.width > width\n }\n }),\n distinctUntilKeyChanged(\"scrollable\")\n )\n}\n\n/**\n * Mount code block\n *\n * This function ensures that an overflowing code block is focusable through\n * keyboard, so it can be scrolled without a mouse to improve on accessibility.\n * Furthermore, if code annotations are enabled, they are mounted if and only\n * if the code block is currently visible, e.g., not in a hidden content tab.\n *\n * @param el - Code block element\n * @param options - Options\n *\n * @returns Code block and annotation component observable\n */\nexport function mountCodeBlock(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const { matches: hover } = matchMedia(\"(hover)\")\n\n /* Defer mounting of code block - see https://bit.ly/3vHVoVD */\n const factory$ = defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ scrollable }) => {\n if (scrollable && hover)\n el.setAttribute(\"tabindex\", \"0\")\n else\n el.removeAttribute(\"tabindex\")\n })\n\n /* Render button for Clipboard.js integration */\n if (ClipboardJS.isSupported()) {\n const parent = el.closest(\"pre\")!\n parent.id = `__code_${++sequence}`\n parent.insertBefore(\n renderClipboardButton(parent.id),\n el\n )\n }\n\n /* Handle code annotations */\n const container = el.closest(\".highlight\")\n if (container instanceof HTMLElement) {\n const list = findCandidateList(container)\n\n /* Mount code annotations, if enabled */\n if (typeof list !== \"undefined\" && (\n container.classList.contains(\"annotate\") ||\n feature(\"content.code.annotate\")\n )) {\n const annotations$ = mountAnnotationList(list, el, options)\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state })),\n mergeWith(\n watchElementSize(container)\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n map(({ width, height }) => width && height),\n distinctUntilChanged(),\n switchMap(active => active ? annotations$ : EMPTY)\n )\n )\n )\n }\n }\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n\n /* Mount code block on first sight */\n return watchElementVisibility(el)\n .pipe(\n filter(visible => visible),\n take(1),\n switchMap(() => factory$)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render an empty annotation\n *\n * @param id - Annotation identifier\n *\n * @returns Element\n */\nexport function renderAnnotation(id: number): HTMLElement {\n return (\n \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a 'copy-to-clipboard' button\n *\n * @param id - Unique identifier\n *\n * @returns Element\n */\nexport function renderClipboardButton(id: string): HTMLElement {\n return (\n code`}\n >\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ComponentChild } from \"preact\"\n\nimport { feature, translation } from \"~/_\"\nimport {\n SearchDocument,\n SearchMetadata,\n SearchResultItem\n} from \"~/integrations/search\"\nimport { h, truncate } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Render flag\n */\nconst enum Flag {\n TEASER = 1, /* Render teaser */\n PARENT = 2 /* Render as parent */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper function\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search document\n *\n * @param document - Search document\n * @param flag - Render flags\n *\n * @returns Element\n */\nfunction renderSearchDocument(\n document: SearchDocument & SearchMetadata, flag: Flag\n): HTMLElement {\n const parent = flag & Flag.PARENT\n const teaser = flag & Flag.TEASER\n\n /* Render missing query terms */\n const missing = Object.keys(document.terms)\n .filter(key => !document.terms[key])\n .reduce((list, key) => [\n ...list, {key}, \" \"\n ], [])\n .slice(0, -1)\n\n /* Assemble query string for highlighting */\n const url = new URL(document.location)\n if (feature(\"search.highlight\"))\n url.searchParams.set(\"h\", Object.entries(document.terms)\n .filter(([, match]) => match)\n .reduce((highlight, [value]) => `${highlight} ${value}`.trim(), \"\")\n )\n\n /* Render article or section, depending on flags */\n return (\n \n \n {parent > 0 &&
    }\n

    {document.title}

    \n {teaser > 0 && document.text.length > 0 &&\n

    \n {truncate(document.text, 320)}\n

    \n }\n {document.tags && document.tags.map(tag => (\n {tag}\n ))}\n {teaser > 0 && missing.length > 0 &&\n

    \n {translation(\"search.result.term.missing\")}: {...missing}\n

    \n }\n \n
    \n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search result\n *\n * @param result - Search result\n *\n * @returns Element\n */\nexport function renderSearchResultItem(\n result: SearchResultItem\n): HTMLElement {\n const threshold = result[0].score\n const docs = [...result]\n\n /* Find and extract parent article */\n const parent = docs.findIndex(doc => !doc.location.includes(\"#\"))\n const [article] = docs.splice(parent, 1)\n\n /* Determine last index above threshold */\n let index = docs.findIndex(doc => doc.score < threshold)\n if (index === -1)\n index = docs.length\n\n /* Partition sections */\n const best = docs.slice(0, index)\n const more = docs.slice(index)\n\n /* Render children */\n const children = [\n renderSearchDocument(article, Flag.PARENT | +(!parent && index === 0)),\n ...best.map(section => renderSearchDocument(section, Flag.TEASER)),\n ...more.length ? [\n
    \n \n {more.length > 0 && more.length === 1\n ? translation(\"search.result.more.one\")\n : translation(\"search.result.more.other\", more.length)\n }\n \n {...more.map(section => renderSearchDocument(section, Flag.TEASER))}\n
    \n ] : []\n ]\n\n /* Render search result */\n return (\n
  • \n {children}\n
  • \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SourceFacts } from \"~/components\"\nimport { h, round } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render repository facts\n *\n * @param facts - Repository facts\n *\n * @returns Element\n */\nexport function renderSourceFacts(facts: SourceFacts): HTMLElement {\n return (\n
      \n {Object.entries(facts).map(([key, value]) => (\n
    • \n {typeof value === \"number\" ? round(value) : value}\n
    • \n ))}\n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a table inside a wrapper to improve scrolling on mobile\n *\n * @param table - Table element\n *\n * @returns Element\n */\nexport function renderTable(table: HTMLElement): HTMLElement {\n return (\n
    \n
    \n {table}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { configuration, translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Version\n */\nexport interface Version {\n version: string /* Version identifier */\n title: string /* Version title */\n aliases: string[] /* Version aliases */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version\n *\n * @param version - Version\n *\n * @returns Element\n */\nfunction renderVersion(version: Version): HTMLElement {\n const config = configuration()\n\n /* Ensure trailing slash, see https://bit.ly/3rL5u3f */\n const url = new URL(`../${version.version}/`, config.base)\n return (\n
  • \n \n {version.title}\n \n
  • \n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version selector\n *\n * @param versions - Versions\n * @param active - Active version\n *\n * @returns Element\n */\nexport function renderVersionSelector(\n versions: Version[], active: Version\n): HTMLElement {\n return (\n
    \n \n {active.title}\n \n
      \n {versions.map(renderVersion)}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n animationFrameScheduler,\n combineLatest,\n defer,\n finalize,\n fromEvent,\n map,\n switchMap,\n take,\n tap,\n throttleTime\n} from \"rxjs\"\n\nimport {\n ElementOffset,\n getElement,\n getElementSize,\n watchElementContentOffset,\n watchElementFocus,\n watchElementOffset\n} from \"~/browser\"\n\nimport { Component } from \"../../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Annotation\n */\nexport interface Annotation {\n active: boolean /* Annotation is active */\n offset: ElementOffset /* Annotation offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n *\n * @returns Annotation observable\n */\nexport function watchAnnotation(\n el: HTMLElement, container: HTMLElement\n): Observable {\n const offset$ = defer(() => combineLatest([\n watchElementOffset(el),\n watchElementContentOffset(container)\n ]))\n .pipe(\n map(([{ x, y }, scroll]) => {\n const { width } = getElementSize(el)\n return ({\n x: x - scroll.x + width / 2,\n y: y - scroll.y\n })\n })\n )\n\n /* Actively watch annotation on focus */\n return watchElementFocus(el)\n .pipe(\n switchMap(active => offset$\n .pipe(\n map(offset => ({ active, offset })),\n take(+!active || Infinity)\n )\n )\n )\n}\n\n/**\n * Mount annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotation(\n el: HTMLElement, container: HTMLElement\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ offset }) {\n el.style.setProperty(\"--md-tooltip-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-tooltip-y\", `${offset.y}px`)\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-x\")\n el.style.removeProperty(\"--md-tooltip-y\")\n }\n })\n\n /* Track relative origin of tooltip */\n push$\n .pipe(\n throttleTime(500, animationFrameScheduler),\n map(() => container.getBoundingClientRect()),\n map(({ x }) => x)\n )\n .subscribe({\n\n /* Handle emission */\n next(origin) {\n if (origin)\n el.style.setProperty(\"--md-tooltip-0\", `${-origin}px`)\n else\n el.style.removeProperty(\"--md-tooltip-0\")\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-0\")\n }\n })\n\n /* Close open annotation on click */\n const index = getElement(\":scope > :last-child\", el)\n const blur$ = fromEvent(index, \"mousedown\", { once: true })\n push$\n .pipe(\n switchMap(({ active }) => active ? blur$ : EMPTY),\n tap(ev => ev.preventDefault())\n )\n .subscribe(() => el.blur())\n\n /* Create and return component */\n return watchAnnotation(el, container)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n finalize,\n merge,\n share,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport {\n getElement,\n getElements,\n getOptionalElement\n} from \"~/browser\"\nimport { renderAnnotation } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotation\n} from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find all annotation markers in the given code block\n *\n * @param container - Containing element\n *\n * @returns Annotation markers\n */\nfunction findAnnotationMarkers(container: HTMLElement): Text[] {\n const markers: Text[] = []\n for (const comment of getElements(\".c, .c1, .cm\", container)) {\n let match: RegExpExecArray | null\n\n /* Split text at marker and add to list */\n let text = comment.firstChild as Text\n if (text instanceof Text)\n while ((match = /\\((\\d+)\\)/.exec(text.textContent!))) {\n const marker = text.splitText(match.index)\n text = marker.splitText(match[0].length)\n markers.push(marker)\n }\n }\n return markers\n}\n\n/**\n * Swap the child nodes of two elements\n *\n * @param source - Source element\n * @param target - Target element\n */\nfunction swap(source: HTMLElement, target: HTMLElement): void {\n target.append(...Array.from(source.childNodes))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount annotation list\n *\n * This function analyzes the containing code block and checks for markers\n * referring to elements in the given annotation list. If no markers are found,\n * the list is left untouched. Otherwise, list elements are rendered as\n * annotations inside the code block.\n *\n * @param el - Annotation list element\n * @param container - Containing element\n * @param options - Options\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotationList(\n el: HTMLElement, container: HTMLElement, { print$ }: MountOptions\n): Observable> {\n\n /* Find and replace all markers with empty annotations */\n const annotations = new Map()\n for (const marker of findAnnotationMarkers(container)) {\n const [, id] = marker.textContent!.match(/\\((\\d+)\\)/)!\n if (getOptionalElement(`li:nth-child(${id})`, el)) {\n annotations.set(+id, renderAnnotation(+id))\n marker.replaceWith(annotations.get(+id)!)\n }\n }\n\n /* Keep list if there are no annotations to render */\n if (annotations.size === 0)\n return EMPTY\n\n /* Create and return component */\n return defer(() => {\n const done$ = new Subject()\n\n /* Handle print mode - see https://bit.ly/3rgPdpt */\n print$\n .pipe(\n takeUntil(done$.pipe(takeLast(1)))\n )\n .subscribe(active => {\n el.hidden = !active\n\n /* Show annotations in code block or list (print) */\n for (const [id, annotation] of annotations) {\n const inner = getElement(\".md-typeset\", annotation)\n const child = getElement(`li:nth-child(${id})`, el)\n if (!active)\n swap(child, inner)\n else\n swap(inner, child)\n }\n })\n\n /* Create and return component */\n return merge(...[...annotations]\n .map(([, annotation]) => (\n mountAnnotation(annotation, container)\n ))\n )\n .pipe(\n finalize(() => done$.complete()),\n share()\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { watchScript } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../../_\"\n\nimport themeCSS from \"./index.css\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid diagram\n */\nexport interface Mermaid {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid instance observable\n */\nlet mermaid$: Observable\n\n/**\n * Global index for Mermaid integration\n */\nlet index = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch Mermaid script\n *\n * @returns Mermaid scripts observable\n */\nfunction fetchScripts(): Observable {\n return typeof mermaid === \"undefined\" || mermaid instanceof Element\n ? watchScript(\"https://unpkg.com/mermaid@9.0.1/dist/mermaid.min.js\")\n : of(undefined)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount Mermaid diagram\n *\n * @param el - Code block element\n *\n * @returns Mermaid diagram component observable\n */\nexport function mountMermaid(\n el: HTMLElement\n): Observable> {\n el.classList.remove(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n mermaid$ ||= fetchScripts()\n .pipe(\n tap(() => mermaid.initialize({\n startOnLoad: false,\n themeCSS\n })),\n map(() => undefined),\n shareReplay(1)\n )\n\n /* Render diagram */\n mermaid$.subscribe(() => {\n el.classList.add(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n const id = `__mermaid_${index++}`\n const host = h(\"div\", { class: \"mermaid\" })\n mermaid.mermaidAPI.render(id, el.textContent, (svg: string) => {\n\n /* Create a shadow root and inject diagram */\n const shadow = host.attachShadow({ mode: \"closed\" })\n shadow.innerHTML = svg\n\n /* Replace code block with diagram */\n el.replaceWith(host)\n })\n })\n\n /* Create and return component */\n return mermaid$\n .pipe(\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n tap\n} from \"rxjs\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Details\n */\nexport interface Details {\n action: \"open\" | \"close\" /* Details state */\n reveal?: boolean /* Details is revealed */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch details\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details observable\n */\nexport function watchDetails(\n el: HTMLDetailsElement, { target$, print$ }: WatchOptions\n): Observable
    {\n let open = true\n return merge(\n\n /* Open and focus details on location target */\n target$\n .pipe(\n map(target => target.closest(\"details:not([open])\")!),\n filter(details => el === details),\n map(() => ({\n action: \"open\", reveal: true\n }) as Details)\n ),\n\n /* Open details on print and close afterwards */\n print$\n .pipe(\n filter(active => active || !open),\n tap(() => open = el.open),\n map(active => ({\n action: active ? \"open\" : \"close\"\n }) as Details)\n )\n )\n}\n\n/**\n * Mount details\n *\n * This function ensures that `details` tags are opened on anchor jumps and\n * prior to printing, so the whole content of the page is visible.\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details component observable\n */\nexport function mountDetails(\n el: HTMLDetailsElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n push$.subscribe(({ action, reveal }) => {\n if (action === \"open\")\n el.setAttribute(\"open\", \"\")\n else\n el.removeAttribute(\"open\")\n if (reveal)\n el.scrollIntoView()\n })\n\n /* Create and return component */\n return watchDetails(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, of } from \"rxjs\"\n\nimport { renderTable } from \"~/templates\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Data table\n */\nexport interface DataTable {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Sentinel for replacement\n */\nconst sentinel = h(\"table\")\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount data table\n *\n * This function wraps a data table in another scrollable container, so it can\n * be smoothly scrolled on smaller screen sizes and won't break the layout.\n *\n * @param el - Data table element\n *\n * @returns Data table component observable\n */\nexport function mountDataTable(\n el: HTMLElement\n): Observable> {\n el.replaceWith(sentinel)\n sentinel.replaceWith(renderTable(el))\n\n /* Create and return component */\n return of({ ref: el })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n asyncScheduler,\n auditTime,\n combineLatest,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n startWith,\n subscribeOn,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport {\n getElement,\n getElementOffset,\n getElementSize,\n getElements,\n watchElementSize\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content tabs\n */\nexport interface ContentTabs {\n active: HTMLLabelElement /* Active tab label */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch content tabs\n *\n * @param el - Content tabs element\n *\n * @returns Content tabs observable\n */\nexport function watchContentTabs(\n el: HTMLElement\n): Observable {\n const inputs = getElements(\":scope > input\", el)\n const active = inputs.find(input => input.checked) || inputs[0]\n return merge(...inputs.map(input => fromEvent(input, \"change\")\n .pipe(\n map(() => ({\n active: getElement(`label[for=${input.id}]`)\n }) as ContentTabs)\n )\n ))\n .pipe(\n startWith({\n active: getElement(`label[for=${active.id}]`)\n } as ContentTabs)\n )\n}\n\n/**\n * Mount content tabs\n *\n * This function scrolls the active tab into view. While this functionality is\n * provided by browsers as part of `scrollInfoView`, browsers will always also\n * scroll the vertical axis, which we do not want. Thus, we decided to provide\n * this functionality ourselves.\n *\n * @param el - Content tabs element\n *\n * @returns Content tabs component observable\n */\nexport function mountContentTabs(\n el: HTMLElement\n): Observable> {\n const container = getElement(\".tabbed-labels\", el)\n return defer(() => {\n const push$ = new Subject()\n combineLatest([push$, watchElementSize(el)])\n .pipe(\n auditTime(1, animationFrameScheduler),\n takeUntil(push$.pipe(takeLast(1)))\n )\n .subscribe({\n\n /* Handle emission */\n next([{ active }]) {\n const offset = getElementOffset(active)\n const { width } = getElementSize(active)\n\n /* Set tab indicator offset and width */\n el.style.setProperty(\"--md-indicator-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-indicator-width\", `${width}px`)\n\n /* Smoothly scroll container */\n container.scrollTo({\n behavior: \"smooth\",\n left: offset.x\n })\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-indicator-x\")\n el.style.removeProperty(\"--md-indicator-width\")\n }\n })\n\n /* Create and return component */\n return watchContentTabs(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n .pipe(\n subscribeOn(asyncScheduler)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, merge } from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Annotation } from \"../annotation\"\nimport {\n CodeBlock,\n Mermaid,\n mountCodeBlock,\n mountMermaid\n} from \"../code\"\nimport {\n Details,\n mountDetails\n} from \"../details\"\nimport {\n DataTable,\n mountDataTable\n} from \"../table\"\nimport {\n ContentTabs,\n mountContentTabs\n} from \"../tabs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content\n */\nexport type Content =\n | Annotation\n | ContentTabs\n | CodeBlock\n | Mermaid\n | DataTable\n | Details\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount content\n *\n * This function mounts all components that are found in the content of the\n * actual article, including code blocks, data tables and details.\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Content component observable\n */\nexport function mountContent(\n el: HTMLElement, { target$, print$ }: MountOptions\n): Observable> {\n return merge(\n\n /* Code blocks */\n ...getElements(\"pre:not(.mermaid) > code\", el)\n .map(child => mountCodeBlock(child, { print$ })),\n\n /* Mermaid diagrams */\n ...getElements(\"pre.mermaid\", el)\n .map(child => mountMermaid(child)),\n\n /* Data tables */\n ...getElements(\"table:not([class])\", el)\n .map(child => mountDataTable(child)),\n\n /* Details */\n ...getElements(\"details\", el)\n .map(child => mountDetails(child, { target$, print$ })),\n\n /* Content tabs */\n ...getElements(\"[data-tabs]\", el)\n .map(child => mountContentTabs(child))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n delay,\n finalize,\n map,\n merge,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Dialog\n */\nexport interface Dialog {\n message: string /* Dialog message */\n active: boolean /* Dialog is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n alert$: Subject /* Alert subject */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch dialog\n *\n * @param _el - Dialog element\n * @param options - Options\n *\n * @returns Dialog observable\n */\nexport function watchDialog(\n _el: HTMLElement, { alert$ }: WatchOptions\n): Observable {\n return alert$\n .pipe(\n switchMap(message => merge(\n of(true),\n of(false).pipe(delay(2000))\n )\n .pipe(\n map(active => ({ message, active }))\n )\n )\n )\n}\n\n/**\n * Mount dialog\n *\n * This function reveals the dialog in the right corner when a new alert is\n * emitted through the subject that is passed as part of the options.\n *\n * @param el - Dialog element\n * @param options - Options\n *\n * @returns Dialog component observable\n */\nexport function mountDialog(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const inner = getElement(\".md-typeset\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ message, active }) => {\n inner.textContent = message\n if (active)\n el.setAttribute(\"data-md-state\", \"open\")\n else\n el.removeAttribute(\"data-md-state\")\n })\n\n /* Create and return component */\n return watchDialog(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n combineLatestWith,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n of,\n shareReplay,\n startWith,\n switchMap,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchToggle\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Main } from \"../../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface Header {\n height: number /* Header visible height */\n hidden: boolean /* Header is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Compute whether the header is hidden\n *\n * If the user scrolls past a certain threshold, the header can be hidden when\n * scrolling down, and shown when scrolling up.\n *\n * @param options - Options\n *\n * @returns Toggle observable\n */\nfunction isHidden({ viewport$ }: WatchOptions): Observable {\n if (!feature(\"header.autohide\"))\n return of(false)\n\n /* Compute direction and turning point */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => [a < b, b] as const),\n distinctUntilKeyChanged(0)\n )\n\n /* Compute whether header should be hidden */\n const hidden$ = combineLatest([viewport$, direction$])\n .pipe(\n filter(([{ offset }, [, y]]) => Math.abs(y - offset.y) > 100),\n map(([, [direction]]) => direction),\n distinctUntilChanged()\n )\n\n /* Compute threshold for hiding */\n const search$ = watchToggle(\"search\")\n return combineLatest([viewport$, search$])\n .pipe(\n map(([{ offset }, search]) => offset.y > 400 && !search),\n distinctUntilChanged(),\n switchMap(active => active ? hidden$ : of(false)),\n startWith(false)\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header observable\n */\nexport function watchHeader(\n el: HTMLElement, options: WatchOptions\n): Observable
    {\n return defer(() => combineLatest([\n watchElementSize(el),\n isHidden(options)\n ]))\n .pipe(\n map(([{ height }, hidden]) => ({\n height,\n hidden\n })),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.hidden === b.hidden\n )),\n shareReplay(1)\n )\n}\n\n/**\n * Mount header\n *\n * This function manages the different states of the header, i.e. whether it's\n * hidden or rendered with a shadow. This depends heavily on the main area.\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header component observable\n */\nexport function mountHeader(\n el: HTMLElement, { header$, main$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n push$\n .pipe(\n distinctUntilKeyChanged(\"active\"),\n combineLatestWith(header$)\n )\n .subscribe(([{ active }, { hidden }]) => {\n if (active)\n el.setAttribute(\"data-md-state\", hidden ? \"hidden\" : \"shadow\")\n else\n el.removeAttribute(\"data-md-state\")\n })\n\n /* Link to main area */\n main$.subscribe(push$)\n\n /* Create and return component */\n return header$\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n tap\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElementSize,\n getOptionalElement,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Header } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface HeaderTitle {\n active: boolean /* Header title is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header title\n *\n * @param el - Heading element\n * @param options - Options\n *\n * @returns Header title observable\n */\nexport function watchHeaderTitle(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchViewportAt(el, { viewport$, header$ })\n .pipe(\n map(({ offset: { y } }) => {\n const { height } = getElementSize(el)\n return {\n active: y >= height\n }\n }),\n distinctUntilKeyChanged(\"active\")\n )\n}\n\n/**\n * Mount header title\n *\n * This function swaps the header title from the site title to the title of the\n * current page when the user scrolls past the first headline.\n *\n * @param el - Header title element\n * @param options - Options\n *\n * @returns Header title component observable\n */\nexport function mountHeaderTitle(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ active }) => {\n if (active)\n el.setAttribute(\"data-md-state\", \"active\")\n else\n el.removeAttribute(\"data-md-state\")\n })\n\n /* Obtain headline, if any */\n const heading = getOptionalElement(\"article h1\")\n if (typeof heading === \"undefined\")\n return EMPTY\n\n /* Create and return component */\n return watchHeaderTitle(heading, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n map,\n switchMap\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchElementSize\n} from \"~/browser\"\n\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Main area\n */\nexport interface Main {\n offset: number /* Main area top offset */\n height: number /* Main area visible height */\n active: boolean /* Main area is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch main area\n *\n * This function returns an observable that computes the visual parameters of\n * the main area which depends on the viewport vertical offset and height, as\n * well as the height of the header element, if the header is fixed.\n *\n * @param el - Main area element\n * @param options - Options\n *\n * @returns Main area observable\n */\nexport function watchMain(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable
    {\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n map(({ height }) => height),\n distinctUntilChanged()\n )\n\n /* Compute the main area's top and bottom borders */\n const border$ = adjust$\n .pipe(\n switchMap(() => watchElementSize(el)\n .pipe(\n map(({ height }) => ({\n top: el.offsetTop,\n bottom: el.offsetTop + height\n })),\n distinctUntilKeyChanged(\"bottom\")\n )\n )\n )\n\n /* Compute the main area's offset, visible height and if we scrolled past */\n return combineLatest([adjust$, border$, viewport$])\n .pipe(\n map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => {\n height = Math.max(0, height\n - Math.max(0, top - y, header)\n - Math.max(0, height + y - bottom)\n )\n return {\n offset: top - header,\n height,\n active: top - header <= y\n }\n }),\n distinctUntilChanged((a, b) => (\n a.offset === b.offset &&\n a.height === b.height &&\n a.active === b.active\n ))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n defer,\n finalize,\n fromEvent,\n map,\n mergeMap,\n observeOn,\n of,\n shareReplay,\n startWith,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Palette colors\n */\nexport interface PaletteColor {\n scheme?: string /* Color scheme */\n primary?: string /* Primary color */\n accent?: string /* Accent color */\n}\n\n/**\n * Palette\n */\nexport interface Palette {\n index: number /* Palette index */\n color: PaletteColor /* Palette colors */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch color palette\n *\n * @param inputs - Color palette element\n *\n * @returns Color palette observable\n */\nexport function watchPalette(\n inputs: HTMLInputElement[]\n): Observable {\n const current = __md_get(\"__palette\") || {\n index: inputs.findIndex(input => matchMedia(\n input.getAttribute(\"data-md-color-media\")!\n ).matches)\n }\n\n /* Emit changes in color palette */\n return of(...inputs)\n .pipe(\n mergeMap(input => fromEvent(input, \"change\")\n .pipe(\n map(() => input)\n )\n ),\n startWith(inputs[Math.max(0, current.index)]),\n map(input => ({\n index: inputs.indexOf(input),\n color: {\n scheme: input.getAttribute(\"data-md-color-scheme\"),\n primary: input.getAttribute(\"data-md-color-primary\"),\n accent: input.getAttribute(\"data-md-color-accent\")\n }\n } as Palette)),\n shareReplay(1)\n )\n}\n\n/**\n * Mount color palette\n *\n * @param el - Color palette element\n *\n * @returns Color palette component observable\n */\nexport function mountPalette(\n el: HTMLElement\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(palette => {\n document.body.setAttribute(\"data-md-color-switching\", \"\")\n\n /* Set color palette */\n for (const [key, value] of Object.entries(palette.color))\n document.body.setAttribute(`data-md-color-${key}`, value)\n\n /* Toggle visibility */\n for (let index = 0; index < inputs.length; index++) {\n const label = inputs[index].nextElementSibling\n if (label instanceof HTMLElement)\n label.hidden = palette.index !== index\n }\n\n /* Persist preference in local storage */\n __md_set(\"__palette\", palette)\n })\n\n /* Revert transition durations after color switch */\n push$.pipe(observeOn(asyncScheduler))\n .subscribe(() => {\n document.body.removeAttribute(\"data-md-color-switching\")\n })\n\n /* Create and return component */\n const inputs = getElements(\"input\", el)\n return watchPalette(inputs)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n Observable,\n Subject,\n map,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport { getElement } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Extract text to copy\n *\n * @param el - HTML element\n *\n * @returns Extracted text\n */\nfunction extract(el: HTMLElement): string {\n el.setAttribute(\"data-md-copying\", \"\")\n const text = el.innerText\n el.removeAttribute(\"data-md-copying\")\n return text\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up Clipboard.js integration\n *\n * @param options - Options\n */\nexport function setupClipboardJS(\n { alert$ }: SetupOptions\n): void {\n if (ClipboardJS.isSupported()) {\n new Observable(subscriber => {\n new ClipboardJS(\"[data-clipboard-target], [data-clipboard-text]\", {\n text: el => (\n el.getAttribute(\"data-clipboard-text\")! ||\n extract(getElement(\n el.getAttribute(\"data-clipboard-target\")!\n ))\n )\n })\n .on(\"success\", ev => subscriber.next(ev))\n })\n .pipe(\n tap(ev => {\n const trigger = ev.trigger as HTMLElement\n trigger.focus()\n }),\n map(() => translation(\"clipboard.copied\"))\n )\n .subscribe(alert$)\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n catchError,\n defaultIfEmpty,\n map,\n of,\n tap\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport { getElements, requestXML } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sitemap, i.e. a list of URLs\n */\nexport type Sitemap = string[]\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Preprocess a list of URLs\n *\n * This function replaces the `site_url` in the sitemap with the actual base\n * URL, to allow instant loading to work in occasions like Netlify previews.\n *\n * @param urls - URLs\n *\n * @returns URL path parts\n */\nfunction preprocess(urls: Sitemap): Sitemap {\n if (urls.length < 2)\n return [\"\"]\n\n /* Take the first two URLs and remove everything after the last slash */\n const [root, next] = [...urls]\n .sort((a, b) => a.length - b.length)\n .map(url => url.replace(/[^/]+$/, \"\"))\n\n /* Compute common prefix */\n let index = 0\n if (root === next)\n index = root.length\n else\n while (root.charCodeAt(index) === next.charCodeAt(index))\n index++\n\n /* Remove common prefix and return in original order */\n return urls.map(url => url.replace(root.slice(0, index), \"\"))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the sitemap for the given base URL\n *\n * @param base - Base URL\n *\n * @returns Sitemap observable\n */\nexport function fetchSitemap(base?: URL): Observable {\n const cached = __md_get(\"__sitemap\", sessionStorage, base)\n if (cached) {\n return of(cached)\n } else {\n const config = configuration()\n return requestXML(new URL(\"sitemap.xml\", base || config.base))\n .pipe(\n map(sitemap => preprocess(getElements(\"loc\", sitemap)\n .map(node => node.textContent!)\n )),\n catchError(() => EMPTY), // @todo refactor instant loading\n defaultIfEmpty([]),\n tap(sitemap => __md_set(\"__sitemap\", sitemap, sessionStorage, base))\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n bufferCount,\n catchError,\n concatMap,\n debounceTime,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n fromEvent,\n map,\n merge,\n of,\n sample,\n share,\n skip,\n skipUntil,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"~/_\"\nimport {\n Viewport,\n ViewportOffset,\n getElements,\n getOptionalElement,\n request,\n setLocation,\n setLocationHash\n} from \"~/browser\"\nimport { getComponentElement } from \"~/components\"\nimport { h } from \"~/utilities\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * History state\n */\nexport interface HistoryState {\n url: URL /* State URL */\n offset?: ViewportOffset /* State viewport offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n location$: Subject /* Location subject */\n viewport$: Observable /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up instant loading\n *\n * When fetching, theoretically, we could use `responseType: \"document\"`, but\n * since all MkDocs links are relative, we need to make sure that the current\n * location matches the document we just loaded. Otherwise any relative links\n * in the document could use the old location.\n *\n * This is the reason why we need to synchronize history events and the process\n * of fetching the document for navigation changes (except `popstate` events):\n *\n * 1. Fetch document via `XMLHTTPRequest`\n * 2. Set new location via `history.pushState`\n * 3. Parse and emit fetched document\n *\n * For `popstate` events, we must not use `history.pushState`, or the forward\n * history will be irreversibly overwritten. In case the request fails, the\n * location change is dispatched regularly.\n *\n * @param options - Options\n */\nexport function setupInstantLoading(\n { document$, location$, viewport$ }: SetupOptions\n): void {\n const config = configuration()\n if (location.protocol === \"file:\")\n return\n\n /* Disable automatic scroll restoration */\n if (\"scrollRestoration\" in history) {\n history.scrollRestoration = \"manual\"\n\n /* Hack: ensure that reloads restore viewport offset */\n fromEvent(window, \"beforeunload\")\n .subscribe(() => {\n history.scrollRestoration = \"auto\"\n })\n }\n\n /* Hack: ensure absolute favicon link to omit 404s when switching */\n const favicon = getOptionalElement(\"link[rel=icon]\")\n if (typeof favicon !== \"undefined\")\n favicon.href = favicon.href\n\n /* Intercept internal navigation */\n const push$ = fetchSitemap()\n .pipe(\n map(paths => paths.map(path => `${new URL(path, config.base)}`)),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n switchMap(ev => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target) {\n const url = new URL(el.href)\n\n /* Canonicalize URL */\n url.search = \"\"\n url.hash = \"\"\n\n /* Check if URL should be intercepted */\n if (\n url.pathname !== location.pathname &&\n urls.includes(url.toString())\n ) {\n ev.preventDefault()\n return of({\n url: new URL(el.href)\n })\n }\n }\n }\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Intercept history back and forward */\n const pop$ = fromEvent(window, \"popstate\")\n .pipe(\n filter(ev => ev.state !== null),\n map(ev => ({\n url: new URL(location.href),\n offset: ev.state\n })),\n share()\n )\n\n /* Emit location change */\n merge(push$, pop$)\n .pipe(\n distinctUntilChanged((a, b) => a.url.href === b.url.href),\n map(({ url }) => url)\n )\n .subscribe(location$)\n\n /* Fetch document via `XMLHTTPRequest` */\n const response$ = location$\n .pipe(\n distinctUntilKeyChanged(\"pathname\"),\n switchMap(url => request(url.href)\n .pipe(\n catchError(() => {\n setLocation(url)\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Set new location via `history.pushState` */\n push$\n .pipe(\n sample(response$)\n )\n .subscribe(({ url }) => {\n history.pushState({}, \"\", `${url}`)\n })\n\n /* Parse and emit fetched document */\n const dom = new DOMParser()\n response$\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/html\"))\n )\n .subscribe(document$)\n\n /* Replace meta tags and components */\n document$\n .pipe(\n skip(1)\n )\n .subscribe(replacement => {\n for (const selector of [\n\n /* Meta tags */\n \"title\",\n \"link[rel=canonical]\",\n \"meta[name=author]\",\n \"meta[name=description]\",\n\n /* Components */\n \"[data-md-component=announce]\",\n \"[data-md-component=container]\",\n \"[data-md-component=header-topic]\",\n \"[data-md-component=outdated]\",\n \"[data-md-component=logo]\",\n \"[data-md-component=skip]\",\n ...feature(\"navigation.tabs.sticky\")\n ? [\"[data-md-component=tabs]\"]\n : []\n ]) {\n const source = getOptionalElement(selector)\n const target = getOptionalElement(selector, replacement)\n if (\n typeof source !== \"undefined\" &&\n typeof target !== \"undefined\"\n ) {\n source.replaceWith(target)\n }\n }\n })\n\n /* Re-evaluate scripts */\n document$\n .pipe(\n skip(1),\n map(() => getComponentElement(\"container\")),\n switchMap(el => getElements(\"script\", el)),\n concatMap(el => {\n const script = h(\"script\")\n if (el.src) {\n for (const name of el.getAttributeNames())\n script.setAttribute(name, el.getAttribute(name)!)\n el.replaceWith(script)\n\n /* Complete when script is loaded */\n return new Observable(observer => {\n script.onload = () => observer.complete()\n })\n\n /* Complete immediately */\n } else {\n script.textContent = el.textContent\n el.replaceWith(script)\n return EMPTY\n }\n })\n )\n .subscribe()\n\n /* Emit history state change */\n merge(push$, pop$)\n .pipe(\n sample(document$)\n )\n .subscribe(({ url, offset }) => {\n if (url.hash && !offset) {\n setLocationHash(url.hash)\n } else {\n window.scrollTo(0, offset?.y || 0)\n }\n })\n\n /* Debounce update of viewport offset */\n viewport$\n .pipe(\n skipUntil(push$),\n debounceTime(250),\n distinctUntilKeyChanged(\"offset\")\n )\n .subscribe(({ offset }) => {\n history.replaceState(offset, \"\")\n })\n\n /* Set viewport offset from history */\n merge(push$, pop$)\n .pipe(\n bufferCount(2, 1),\n filter(([a, b]) => a.url.pathname === b.url.pathname),\n map(([, state]) => state)\n )\n .subscribe(({ offset }) => {\n window.scrollTo(0, offset?.y || 0)\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexDocument } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search document\n */\nexport interface SearchDocument extends SearchIndexDocument {\n parent?: SearchIndexDocument /* Parent article */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search document mapping\n */\nexport type SearchDocumentMap = Map\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search document mapping\n *\n * @param docs - Search index documents\n *\n * @returns Search document map\n */\nexport function setupSearchDocumentMap(\n docs: SearchIndexDocument[]\n): SearchDocumentMap {\n const documents = new Map()\n const parents = new Set()\n for (const doc of docs) {\n const [path, hash] = doc.location.split(\"#\")\n\n /* Extract location, title and tags */\n const location = doc.location\n const title = doc.title\n const tags = doc.tags\n\n /* Escape and cleanup text */\n const text = escapeHTML(doc.text)\n .replace(/\\s+(?=[,.:;!?])/g, \"\")\n .replace(/\\s+/g, \" \")\n\n /* Handle section */\n if (hash) {\n const parent = documents.get(path)!\n\n /* Ignore first section, override article */\n if (!parents.has(parent)) {\n parent.title = doc.title\n parent.text = text\n\n /* Remember that we processed the article */\n parents.add(parent)\n\n /* Add subsequent section */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n parent\n })\n }\n\n /* Add article */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n ...tags && { tags }\n })\n }\n }\n return documents\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexConfig } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlight function\n *\n * @param value - Value\n *\n * @returns Highlighted value\n */\nexport type SearchHighlightFn = (value: string) => string\n\n/**\n * Search highlight factory function\n *\n * @param query - Query value\n *\n * @returns Search highlight function\n */\nexport type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search highlighter\n *\n * @param config - Search index configuration\n * @param escape - Whether to escape HTML\n *\n * @returns Search highlight factory function\n */\nexport function setupSearchHighlighter(\n config: SearchIndexConfig, escape: boolean\n): SearchHighlightFactoryFn {\n const separator = new RegExp(config.separator, \"img\")\n const highlight = (_: unknown, data: string, term: string) => {\n return `${data}${term}`\n }\n\n /* Return factory function */\n return (query: string) => {\n query = query\n .replace(/[\\s*+\\-:~^]+/g, \" \")\n .trim()\n\n /* Create search term match expression */\n const match = new RegExp(`(^|${config.separator})(${\n query\n .replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\")\n .replace(separator, \"|\")\n })`, \"img\")\n\n /* Highlight string value */\n return value => (\n escape\n ? escapeHTML(value)\n : value\n )\n .replace(match, highlight)\n .replace(/<\\/mark>(\\s+)]*>/img, \"$1\")\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search transformation function\n *\n * @param value - Query value\n *\n * @returns Transformed query value\n */\nexport type SearchTransformFn = (value: string) => string\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Default transformation function\n *\n * 1. Search for terms in quotation marks and prepend a `+` modifier to denote\n * that the resulting document must contain all terms, converting the query\n * to an `AND` query (as opposed to the default `OR` behavior). While users\n * may expect terms enclosed in quotation marks to map to span queries, i.e.\n * for which order is important, Lunr.js doesn't support them, so the best\n * we can do is to convert the terms to an `AND` query.\n *\n * 2. Replace control characters which are not located at the beginning of the\n * query or preceded by white space, or are not followed by a non-whitespace\n * character or are at the end of the query string. Furthermore, filter\n * unmatched quotation marks.\n *\n * 3. Trim excess whitespace from left and right.\n *\n * @param query - Query value\n *\n * @returns Transformed query value\n */\nexport function defaultTransform(query: string): string {\n return query\n .split(/\"([^\"]+)\"/g) /* => 1 */\n .map((terms, index) => index & 1\n ? terms.replace(/^\\b|^(?![^\\x00-\\x7F]|$)|\\s+/g, \" +\")\n : terms\n )\n .join(\"\")\n .replace(/\"|(?:^|\\s+)[*+\\-:^~]+(?=\\s+|$)/g, \"\") /* => 2 */\n .trim() /* => 3 */\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SearchIndex, SearchResult } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search message type\n */\nexport const enum SearchMessageType {\n SETUP, /* Search index setup */\n READY, /* Search index ready */\n QUERY, /* Search query */\n RESULT /* Search results */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message containing the data necessary to setup the search index\n */\nexport interface SearchSetupMessage {\n type: SearchMessageType.SETUP /* Message type */\n data: SearchIndex /* Message data */\n}\n\n/**\n * Message indicating the search index is ready\n */\nexport interface SearchReadyMessage {\n type: SearchMessageType.READY /* Message type */\n}\n\n/**\n * Message containing a search query\n */\nexport interface SearchQueryMessage {\n type: SearchMessageType.QUERY /* Message type */\n data: string /* Message data */\n}\n\n/**\n * Message containing results for a search query\n */\nexport interface SearchResultMessage {\n type: SearchMessageType.RESULT /* Message type */\n data: SearchResult /* Message data */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message exchanged with the search worker\n */\nexport type SearchMessage =\n | SearchSetupMessage\n | SearchReadyMessage\n | SearchQueryMessage\n | SearchResultMessage\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Type guard for search setup messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchSetupMessage(\n message: SearchMessage\n): message is SearchSetupMessage {\n return message.type === SearchMessageType.SETUP\n}\n\n/**\n * Type guard for search ready messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchReadyMessage(\n message: SearchMessage\n): message is SearchReadyMessage {\n return message.type === SearchMessageType.READY\n}\n\n/**\n * Type guard for search query messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchQueryMessage(\n message: SearchMessage\n): message is SearchQueryMessage {\n return message.type === SearchMessageType.QUERY\n}\n\n/**\n * Type guard for search result messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchResultMessage(\n message: SearchMessage\n): message is SearchResultMessage {\n return message.type === SearchMessageType.RESULT\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ObservableInput,\n Subject,\n from,\n map,\n share\n} from \"rxjs\"\n\nimport { configuration, feature, translation } from \"~/_\"\nimport { WorkerHandler, watchWorker } from \"~/browser\"\n\nimport { SearchIndex } from \"../../_\"\nimport {\n SearchOptions,\n SearchPipeline\n} from \"../../options\"\nimport {\n SearchMessage,\n SearchMessageType,\n SearchSetupMessage,\n isSearchResultMessage\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search worker\n */\nexport type SearchWorker = WorkerHandler\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search index\n *\n * @param data - Search index\n *\n * @returns Search index\n */\nfunction setupSearchIndex({ config, docs }: SearchIndex): SearchIndex {\n\n /* Override default language with value from translation */\n if (config.lang.length === 1 && config.lang[0] === \"en\")\n config.lang = [\n translation(\"search.config.lang\")\n ]\n\n /* Override default separator with value from translation */\n if (config.separator === \"[\\\\s\\\\-]+\")\n config.separator = translation(\"search.config.separator\")\n\n /* Set pipeline from translation */\n const pipeline = translation(\"search.config.pipeline\")\n .split(/\\s*,\\s*/)\n .filter(Boolean) as SearchPipeline\n\n /* Determine search options */\n const options: SearchOptions = {\n pipeline,\n suggestions: feature(\"search.suggest\")\n }\n\n /* Return search index after defaulting */\n return { config, docs, options }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search worker\n *\n * This function creates a web worker to set up and query the search index,\n * which is done using Lunr.js. The index must be passed as an observable to\n * enable hacks like _localsearch_ via search index embedding as JSON.\n *\n * @param url - Worker URL\n * @param index - Search index observable input\n *\n * @returns Search worker\n */\nexport function setupSearchWorker(\n url: string, index: ObservableInput\n): SearchWorker {\n const config = configuration()\n const worker = new Worker(url)\n\n /* Create communication channels and resolve relative links */\n const tx$ = new Subject()\n const rx$ = watchWorker(worker, { tx$ })\n .pipe(\n map(message => {\n if (isSearchResultMessage(message)) {\n for (const result of message.data.items)\n for (const document of result)\n document.location = `${new URL(document.location, config.base)}`\n }\n return message\n }),\n share()\n )\n\n /* Set up search index */\n from(index)\n .pipe(\n map(data => ({\n type: SearchMessageType.SETUP,\n data: setupSearchIndex(data)\n } as SearchSetupMessage))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Return search worker */\n return { tx$, rx$ }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Subject,\n catchError,\n combineLatest,\n filter,\n fromEvent,\n map,\n of,\n switchMap\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n getElement,\n getLocation,\n requestJSON,\n setLocation\n} from \"~/browser\"\nimport { getComponentElements } from \"~/components\"\nimport {\n Version,\n renderVersionSelector\n} from \"~/templates\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up version selector\n *\n * @param options - Options\n */\nexport function setupVersionSelector(\n { document$ }: SetupOptions\n): void {\n const config = configuration()\n const versions$ = requestJSON(\n new URL(\"../versions.json\", config.base)\n )\n .pipe(\n catchError(() => EMPTY) // @todo refactor instant loading\n )\n\n /* Determine current version */\n const current$ = versions$\n .pipe(\n map(versions => {\n const [, current] = config.base.match(/([^/]+)\\/?$/)!\n return versions.find(({ version, aliases }) => (\n version === current || aliases.includes(current)\n )) || versions[0]\n })\n )\n\n /* Intercept inter-version navigation */\n combineLatest([versions$, current$])\n .pipe(\n map(([versions, current]) => new Map(versions\n .filter(version => version !== current)\n .map(version => [\n `${new URL(`../${version.version}/`, config.base)}`,\n version\n ])\n )),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n switchMap(ev => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target && urls.has(el.href)) {\n ev.preventDefault()\n return of(el.href)\n }\n }\n return EMPTY\n }),\n switchMap(url => {\n const { version } = urls.get(url)!\n return fetchSitemap(new URL(url))\n .pipe(\n map(sitemap => {\n const location = getLocation()\n const path = location.href.replace(config.base, \"\")\n return sitemap.includes(path)\n ? new URL(`../${version}/${path}`, config.base)\n : new URL(url)\n })\n )\n })\n )\n )\n )\n .subscribe(url => setLocation(url))\n\n /* Render version selector and warning */\n combineLatest([versions$, current$])\n .subscribe(([versions, current]) => {\n const topic = getElement(\".md-header__topic\")\n topic.appendChild(renderVersionSelector(versions, current))\n })\n\n /* Integrate outdated version banner with instant loading */\n document$.pipe(switchMap(() => current$))\n .subscribe(current => {\n\n /* Check if version state was already determined */\n let outdated = __md_get(\"__outdated\", sessionStorage)\n if (outdated === null) {\n const latest = config.version?.default || \"latest\"\n outdated = !current.aliases.includes(latest)\n\n /* Persist version state in session storage */\n __md_set(\"__outdated\", outdated, sessionStorage)\n }\n\n /* Unhide outdated version banner */\n if (outdated)\n for (const warning of getComponentElements(\"outdated\"))\n warning.hidden = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n combineLatest,\n delay,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n shareReplay,\n startWith,\n take,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getLocation,\n setToggle,\n watchElementFocus,\n watchToggle\n} from \"~/browser\"\nimport {\n SearchMessageType,\n SearchQueryMessage,\n SearchWorker,\n defaultTransform,\n isSearchReadyMessage\n} from \"~/integrations\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query\n */\nexport interface SearchQuery {\n value: string /* Query value */\n focus: boolean /* Query focus */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch search query\n *\n * Note that the focus event which triggers re-reading the current query value\n * is delayed by `1ms` so the input's empty state is allowed to propagate.\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query observable\n */\nexport function watchSearchQuery(\n el: HTMLInputElement, { rx$ }: SearchWorker\n): Observable {\n const fn = __search?.transform || defaultTransform\n\n /* Immediately show search dialog */\n const { searchParams } = getLocation()\n if (searchParams.has(\"q\"))\n setToggle(\"search\", true)\n\n /* Intercept query parameter (deep link) */\n const param$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1),\n map(() => searchParams.get(\"q\") || \"\")\n )\n\n /* Remove query parameter when search is closed */\n watchToggle(\"search\")\n .pipe(\n filter(active => !active),\n take(1)\n )\n .subscribe(() => {\n const url = new URL(location.href)\n url.searchParams.delete(\"q\")\n history.replaceState({}, \"\", `${url}`)\n })\n\n /* Set query from parameter */\n param$.subscribe(value => { // TODO: not ideal - find a better way\n if (value) {\n el.value = value\n el.focus()\n }\n })\n\n /* Intercept focus and input events */\n const focus$ = watchElementFocus(el)\n const value$ = merge(\n fromEvent(el, \"keyup\"),\n fromEvent(el, \"focus\").pipe(delay(1)),\n param$\n )\n .pipe(\n map(() => fn(el.value)),\n startWith(\"\"),\n distinctUntilChanged(),\n )\n\n /* Combine into single observable */\n return combineLatest([value$, focus$])\n .pipe(\n map(([value, focus]) => ({ value, focus })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount search query\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query component observable\n */\nexport function mountSearchQuery(\n el: HTMLInputElement, { tx$, rx$ }: SearchWorker\n): Observable> {\n const push$ = new Subject()\n\n /* Handle value changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"value\"),\n map(({ value }): SearchQueryMessage => ({\n type: SearchMessageType.QUERY,\n data: value\n }))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Handle focus changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"focus\")\n )\n .subscribe(({ focus }) => {\n if (focus) {\n setToggle(\"search\", focus)\n el.placeholder = \"\"\n } else {\n el.placeholder = translation(\"search.placeholder\")\n }\n })\n\n /* Handle reset */\n fromEvent(el.form!, \"reset\")\n .pipe(\n takeUntil(push$.pipe(takeLast(1)))\n )\n .subscribe(() => el.focus())\n\n /* Create and return component */\n return watchSearchQuery(el, { tx$, rx$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n filter,\n finalize,\n map,\n merge,\n of,\n skipUntil,\n switchMap,\n take,\n tap,\n withLatestFrom,\n zipWith\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getElement,\n watchElementBoundary\n} from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchReadyMessage,\n isSearchResultMessage\n} from \"~/integrations\"\nimport { renderSearchResultItem } from \"~/templates\"\nimport { round } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search result list\n *\n * This function performs a lazy rendering of the search results, depending on\n * the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchResult(\n el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n const boundary$ = watchElementBoundary(el.parentElement!)\n .pipe(\n filter(Boolean)\n )\n\n /* Retrieve nested components */\n const meta = getElement(\":scope > :first-child\", el)\n const list = getElement(\":scope > :last-child\", el)\n\n /* Wait until search is ready */\n const ready$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1)\n )\n\n /* Update search result metadata */\n push$\n .pipe(\n withLatestFrom(query$),\n skipUntil(ready$)\n )\n .subscribe(([{ items }, { value }]) => {\n if (value) {\n switch (items.length) {\n\n /* No results */\n case 0:\n meta.textContent = translation(\"search.result.none\")\n break\n\n /* One result */\n case 1:\n meta.textContent = translation(\"search.result.one\")\n break\n\n /* Multiple result */\n default:\n meta.textContent = translation(\n \"search.result.other\",\n round(items.length)\n )\n }\n } else {\n meta.textContent = translation(\"search.result.placeholder\")\n }\n })\n\n /* Update search result list */\n push$\n .pipe(\n tap(() => list.innerHTML = \"\"),\n switchMap(({ items }) => merge(\n of(...items.slice(0, 10)),\n of(...items.slice(10))\n .pipe(\n bufferCount(4),\n zipWith(boundary$),\n switchMap(([chunk]) => chunk)\n )\n ))\n )\n .subscribe(result => list.appendChild(\n renderSearchResultItem(result)\n ))\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n finalize,\n fromEvent,\n map,\n tap\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search sharing\n */\nexport interface SearchShare {\n url: URL /* Deep link for sharing */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n query$: Observable /* Search query observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search sharing\n *\n * @param _el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing observable\n */\nexport function watchSearchShare(\n _el: HTMLElement, { query$ }: WatchOptions\n): Observable {\n return query$\n .pipe(\n map(({ value }) => {\n const url = getLocation()\n url.hash = \"\"\n url.searchParams.delete(\"h\")\n url.searchParams.set(\"q\", value)\n return { url }\n })\n )\n}\n\n/**\n * Mount search sharing\n *\n * @param el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing component observable\n */\nexport function mountSearchShare(\n el: HTMLAnchorElement, options: MountOptions\n): Observable> {\n const push$ = new Subject()\n push$.subscribe(({ url }) => {\n el.setAttribute(\"data-clipboard-text\", el.href)\n el.href = `${url}`\n })\n\n /* Prevent following of link */\n fromEvent(el, \"click\")\n .subscribe(ev => ev.preventDefault())\n\n /* Create and return component */\n return watchSearchShare(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n combineLatestWith,\n distinctUntilChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n observeOn,\n tap\n} from \"rxjs\"\n\nimport { Keyboard } from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchResultMessage\n} from \"~/integrations\"\n\nimport { Component, getComponentElement } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search suggestions\n */\nexport interface SearchSuggest {}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search suggestions\n *\n * This function will perform a lazy rendering of the search results, depending\n * on the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchSuggest(\n el: HTMLElement, { rx$ }: SearchWorker, { keyboard$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n\n /* Retrieve query component and track all changes */\n const query = getComponentElement(\"search-query\")\n const query$ = merge(\n fromEvent(query, \"keydown\"),\n fromEvent(query, \"focus\")\n )\n .pipe(\n observeOn(asyncScheduler),\n map(() => query.value),\n distinctUntilChanged(),\n )\n\n /* Update search suggestions */\n push$\n .pipe(\n combineLatestWith(query$),\n map(([{ suggestions }, value]) => {\n const words = value.split(/([\\s-]+)/)\n if (suggestions?.length && words[words.length - 1]) {\n const last = suggestions[suggestions.length - 1]\n if (last.startsWith(words[words.length - 1]))\n words[words.length - 1] = last\n } else {\n words.length = 0\n }\n return words\n })\n )\n .subscribe(words => el.innerHTML = words\n .join(\"\")\n .replace(/\\s/g, \" \")\n )\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Right arrow: accept current suggestion */\n case \"ArrowRight\":\n if (\n el.innerText.length &&\n query.selectionStart === query.value.length\n )\n query.value = el.innerText\n break\n }\n })\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n ObservableInput,\n filter,\n merge,\n mergeWith,\n sample,\n take\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n Keyboard,\n getActiveElement,\n getElements,\n setToggle\n} from \"~/browser\"\nimport {\n SearchIndex,\n SearchResult,\n isSearchQueryMessage,\n isSearchReadyMessage,\n setupSearchWorker\n} from \"~/integrations\"\n\nimport {\n Component,\n getComponentElement,\n getComponentElements\n} from \"../../_\"\nimport {\n SearchQuery,\n mountSearchQuery\n} from \"../query\"\nimport { mountSearchResult } from \"../result\"\nimport {\n SearchShare,\n mountSearchShare\n} from \"../share\"\nimport {\n SearchSuggest,\n mountSearchSuggest\n} from \"../suggest\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search\n */\nexport type Search =\n | SearchQuery\n | SearchResult\n | SearchShare\n | SearchSuggest\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search\n *\n * This function sets up the search functionality, including the underlying\n * web worker and all keyboard bindings.\n *\n * @param el - Search element\n * @param options - Options\n *\n * @returns Search component observable\n */\nexport function mountSearch(\n el: HTMLElement, { index$, keyboard$ }: MountOptions\n): Observable> {\n const config = configuration()\n try {\n const url = __search?.worker || config.search\n const worker = setupSearchWorker(url, index$)\n\n /* Retrieve query and result components */\n const query = getComponentElement(\"search-query\", el)\n const result = getComponentElement(\"search-result\", el)\n\n /* Re-emit query when search is ready */\n const { tx$, rx$ } = worker\n tx$\n .pipe(\n filter(isSearchQueryMessage),\n sample(rx$.pipe(filter(isSearchReadyMessage))),\n take(1)\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n const active = getActiveElement()\n switch (key.type) {\n\n /* Enter: go to first (best) result */\n case \"Enter\":\n if (active === query) {\n const anchors = new Map()\n for (const anchor of getElements(\n \":first-child [href]\", result\n )) {\n const article = anchor.firstElementChild!\n anchors.set(anchor, parseFloat(\n article.getAttribute(\"data-md-score\")!\n ))\n }\n\n /* Go to result with highest score, if any */\n if (anchors.size) {\n const [[best]] = [...anchors].sort(([, a], [, b]) => b - a)\n best.click()\n }\n\n /* Otherwise omit form submission */\n key.claim()\n }\n break\n\n /* Escape or Tab: close search */\n case \"Escape\":\n case \"Tab\":\n setToggle(\"search\", false)\n query.blur()\n break\n\n /* Vertical arrows: select previous or next search result */\n case \"ArrowUp\":\n case \"ArrowDown\":\n if (typeof active === \"undefined\") {\n query.focus()\n } else {\n const els = [query, ...getElements(\n \":not(details) > [href], summary, details[open] [href]\",\n result\n )]\n const i = Math.max(0, (\n Math.max(0, els.indexOf(active)) + els.length + (\n key.type === \"ArrowUp\" ? -1 : +1\n )\n ) % els.length)\n els[i].focus()\n }\n\n /* Prevent scrolling of page */\n key.claim()\n break\n\n /* All other keys: hand to search query */\n default:\n if (query !== getActiveElement())\n query.focus()\n }\n })\n\n /* Set up global keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\"),\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Open search and select query */\n case \"f\":\n case \"s\":\n case \"/\":\n query.focus()\n query.select()\n\n /* Prevent scrolling of page */\n key.claim()\n break\n }\n })\n\n /* Create and return component */\n const query$ = mountSearchQuery(query, worker)\n const result$ = mountSearchResult(result, worker, { query$ })\n return merge(query$, result$)\n .pipe(\n mergeWith(\n\n /* Search sharing */\n ...getComponentElements(\"search-share\", el)\n .map(child => mountSearchShare(child, { query$ })),\n\n /* Search suggestions */\n ...getComponentElements(\"search-suggest\", el)\n .map(child => mountSearchSuggest(child, worker, { keyboard$ }))\n )\n )\n\n /* Gracefully handle broken search */\n } catch (err) {\n el.hidden = true\n return NEVER\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n ObservableInput,\n combineLatest,\n filter,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\nimport {\n SearchIndex,\n setupSearchHighlighter\n} from \"~/integrations\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlighting\n */\nexport interface SearchHighlight {\n nodes: Map /* Map of replacements */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n location$: Observable /* Location observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search highlighting\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Search highlighting component observable\n */\nexport function mountSearchHiglight(\n el: HTMLElement, { index$, location$ }: MountOptions\n): Observable> {\n return combineLatest([\n index$,\n location$\n .pipe(\n startWith(getLocation()),\n filter(url => !!url.searchParams.get(\"h\"))\n )\n ])\n .pipe(\n map(([index, url]) => setupSearchHighlighter(index.config, true)(\n url.searchParams.get(\"h\")!\n )),\n map(fn => {\n const nodes = new Map()\n\n /* Traverse text nodes and collect matches */\n const it = document.createNodeIterator(el, NodeFilter.SHOW_TEXT)\n for (let node = it.nextNode(); node; node = it.nextNode()) {\n if (node.parentElement?.offsetHeight) {\n const original = node.textContent!\n const replaced = fn(original)\n if (replaced.length > original.length)\n nodes.set(node as ChildNode, replaced)\n }\n }\n\n /* Replace original nodes with matches */\n for (const [node, text] of nodes) {\n const { childNodes } = h(\"span\", null, text)\n node.replaceWith(...Array.from(childNodes))\n }\n\n /* Return component */\n return { ref: el, nodes }\n })\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n auditTime,\n combineLatest,\n defer,\n distinctUntilChanged,\n finalize,\n map,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElement,\n getElementOffset\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sidebar\n */\nexport interface Sidebar {\n height: number /* Sidebar height */\n locked: boolean /* Sidebar is locked */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch sidebar\n *\n * This function returns an observable that computes the visual parameters of\n * the sidebar which depends on the vertical viewport offset, as well as the\n * height of the main area. When the page is scrolled beyond the header, the\n * sidebar is locked and fills the remaining space.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar observable\n */\nexport function watchSidebar(\n el: HTMLElement, { viewport$, main$ }: WatchOptions\n): Observable {\n const parent = el.parentElement!\n const adjust =\n parent.offsetTop -\n parent.parentElement!.offsetTop\n\n /* Compute the sidebar's available height and if it should be locked */\n return combineLatest([main$, viewport$])\n .pipe(\n map(([{ offset, height }, { offset: { y } }]) => {\n height = height\n + Math.min(adjust, Math.max(0, y - offset))\n - adjust\n return {\n height,\n locked: y >= offset + adjust\n }\n }),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.locked === b.locked\n ))\n )\n}\n\n/**\n * Mount sidebar\n *\n * This function doesn't set the height of the actual sidebar, but of its first\n * child \u2013 the `.md-sidebar__scrollwrap` element in order to mitigiate jittery\n * sidebars when the footer is scrolled into view. At some point we switched\n * from `absolute` / `fixed` positioning to `sticky` positioning, significantly\n * reducing jitter in some browsers (respectively Firefox and Safari) when\n * scrolling from the top. However, top-aligned sticky positioning means that\n * the sidebar snaps to the bottom when the end of the container is reached.\n * This is what leads to the mentioned jitter, as the sidebar's height may be\n * updated too slowly.\n *\n * This behaviour can be mitigiated by setting the height of the sidebar to `0`\n * while preserving the padding, and the height on its first element.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar component observable\n */\nexport function mountSidebar(\n el: HTMLElement, { header$, ...options }: MountOptions\n): Observable> {\n const inner = getElement(\".md-sidebar__scrollwrap\", el)\n const { y } = getElementOffset(inner)\n return defer(() => {\n const push$ = new Subject()\n push$\n .pipe(\n auditTime(0, animationFrameScheduler),\n withLatestFrom(header$)\n )\n .subscribe({\n\n /* Handle emission */\n next([{ height }, { height: offset }]) {\n inner.style.height = `${height - 2 * y}px`\n el.style.top = `${offset}px`\n },\n\n /* Handle complete */\n complete() {\n inner.style.height = \"\"\n el.style.top = \"\"\n }\n })\n\n /* Create and return component */\n return watchSidebar(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Repo, User } from \"github-types\"\nimport {\n EMPTY,\n Observable,\n catchError,\n defaultIfEmpty,\n map,\n zip\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * GitHub release (partial)\n */\ninterface Release {\n tag_name: string /* Tag name */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitHub repository facts\n *\n * @param user - GitHub user or organization\n * @param repo - GitHub repository\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitHub(\n user: string, repo?: string\n): Observable {\n if (typeof repo !== \"undefined\") {\n const url = `https://api.github.com/repos/${user}/${repo}`\n return zip(\n\n /* Fetch version */\n requestJSON(`${url}/releases/latest`)\n .pipe(\n catchError(() => EMPTY), // @todo refactor instant loading\n map(release => ({\n version: release.tag_name\n })),\n defaultIfEmpty({})\n ),\n\n /* Fetch stars and forks */\n requestJSON(url)\n .pipe(\n catchError(() => EMPTY), // @todo refactor instant loading\n map(info => ({\n stars: info.stargazers_count,\n forks: info.forks_count\n })),\n defaultIfEmpty({})\n )\n )\n .pipe(\n map(([release, info]) => ({ ...release, ...info }))\n )\n\n /* User or organization */\n } else {\n const url = `https://api.github.com/users/${user}`\n return requestJSON(url)\n .pipe(\n map(info => ({\n repositories: info.public_repos\n })),\n defaultIfEmpty({})\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ProjectSchema } from \"gitlab\"\nimport {\n EMPTY,\n Observable,\n catchError,\n defaultIfEmpty,\n map\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitLab repository facts\n *\n * @param base - GitLab base\n * @param project - GitLab project\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitLab(\n base: string, project: string\n): Observable {\n const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}`\n return requestJSON(url)\n .pipe(\n catchError(() => EMPTY), // @todo refactor instant loading\n map(({ star_count, forks_count }) => ({\n stars: star_count,\n forks: forks_count\n })),\n defaultIfEmpty({})\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { EMPTY, Observable } from \"rxjs\"\n\nimport { fetchSourceFactsFromGitHub } from \"../github\"\nimport { fetchSourceFactsFromGitLab } from \"../gitlab\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository facts for repositories\n */\nexport interface RepositoryFacts {\n stars?: number /* Number of stars */\n forks?: number /* Number of forks */\n version?: string /* Latest version */\n}\n\n/**\n * Repository facts for organizations\n */\nexport interface OrganizationFacts {\n repositories?: number /* Number of repositories */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Repository facts\n */\nexport type SourceFacts =\n | RepositoryFacts\n | OrganizationFacts\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch repository facts\n *\n * @param url - Repository URL\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFacts(\n url: string\n): Observable {\n const [type] = url.match(/(git(?:hub|lab))/i) || []\n switch (type.toLowerCase()) {\n\n /* GitHub repository */\n case \"github\":\n const [, user, repo] = url.match(/^.+github\\.com\\/([^/]+)\\/?([^/]+)?/i)!\n return fetchSourceFactsFromGitHub(user, repo)\n\n /* GitLab repository */\n case \"gitlab\":\n const [, base, slug] = url.match(/^.+?([^/]*gitlab[^/]+)\\/(.+?)\\/?$/i)!\n return fetchSourceFactsFromGitLab(base, slug)\n\n /* Everything else */\n default:\n return EMPTY\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n catchError,\n defer,\n filter,\n finalize,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\nimport { renderSourceFacts } from \"~/templates\"\n\nimport { Component } from \"../../_\"\nimport {\n SourceFacts,\n fetchSourceFacts\n} from \"../facts\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information\n */\nexport interface Source {\n facts: SourceFacts /* Repository facts */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information observable\n */\nlet fetch$: Observable\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch repository information\n *\n * This function tries to read the repository facts from session storage, and\n * if unsuccessful, fetches them from the underlying provider.\n *\n * @param el - Repository information element\n *\n * @returns Repository information observable\n */\nexport function watchSource(\n el: HTMLAnchorElement\n): Observable {\n return fetch$ ||= defer(() => {\n const cached = __md_get(\"__source\", sessionStorage)\n if (cached)\n return of(cached)\n else\n return fetchSourceFacts(el.href)\n .pipe(\n tap(facts => __md_set(\"__source\", facts, sessionStorage))\n )\n })\n .pipe(\n catchError(() => EMPTY),\n filter(facts => Object.keys(facts).length > 0),\n map(facts => ({ facts })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount repository information\n *\n * @param el - Repository information element\n *\n * @returns Repository information component observable\n */\nexport function mountSource(\n el: HTMLAnchorElement\n): Observable> {\n const inner = getElement(\":scope > :last-child\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ facts }) => {\n inner.appendChild(renderSourceFacts(facts))\n inner.setAttribute(\"data-md-state\", \"done\")\n })\n\n /* Create and return component */\n return watchSource(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Navigation tabs\n */\nexport interface Tabs {\n hidden: boolean /* Navigation tabs are hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch navigation tabs\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs observable\n */\nexport function watchTabs(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchElementSize(document.body)\n .pipe(\n switchMap(() => watchViewportAt(el, { header$, viewport$ })),\n map(({ offset: { y } }) => {\n return {\n hidden: y >= 10\n }\n }),\n distinctUntilKeyChanged(\"hidden\")\n )\n}\n\n/**\n * Mount navigation tabs\n *\n * This function hides the navigation tabs when scrolling past the threshold\n * and makes them reappear in a nice CSS animation when scrolling back up.\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs component observable\n */\nexport function mountTabs(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n if (hidden)\n el.setAttribute(\"data-md-state\", \"hidden\")\n else\n el.removeAttribute(\"data-md-state\")\n },\n\n /* Handle complete */\n complete() {\n el.removeAttribute(\"data-md-state\")\n }\n })\n\n /* Create and return component */\n return (\n feature(\"navigation.tabs.sticky\")\n ? of({ hidden: false })\n : watchTabs(el, options)\n )\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatestWith,\n debounceTime,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n of,\n repeat,\n scan,\n share,\n skip,\n startWith,\n switchMap,\n takeLast,\n takeUntil,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n getElement,\n getElements,\n getLocation,\n getOptionalElement,\n watchElementSize\n} from \"~/browser\"\n\nimport {\n Component,\n getComponentElement\n} from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Table of contents\n */\nexport interface TableOfContents {\n prev: HTMLAnchorElement[][] /* Anchors (previous) */\n next: HTMLAnchorElement[][] /* Anchors (next) */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch table of contents\n *\n * This is effectively a scroll spy implementation which will account for the\n * fixed header and automatically re-calculate anchor offsets when the viewport\n * is resized. The returned observable will only emit if the table of contents\n * needs to be repainted.\n *\n * This implementation tracks an anchor element's entire path starting from its\n * level up to the top-most anchor element, e.g. `[h3, h2, h1]`. Although the\n * Material theme currently doesn't make use of this information, it enables\n * the styling of the entire hierarchy through customization.\n *\n * Note that the current anchor is the last item of the `prev` anchor list.\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents observable\n */\nexport function watchTableOfContents(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const table = new Map()\n\n /* Compute anchor-to-target mapping */\n const anchors = getElements(\"[href^=\\\\#]\", el)\n for (const anchor of anchors) {\n const id = decodeURIComponent(anchor.hash.substring(1))\n const target = getOptionalElement(`[id=\"${id}\"]`)\n if (typeof target !== \"undefined\")\n table.set(anchor, target)\n }\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n map(({ height }) => {\n const main = getComponentElement(\"main\")\n const grid = getElement(\":scope > :first-child\", main)\n return height + 0.8 * (\n grid.offsetTop -\n main.offsetTop\n )\n }),\n share()\n )\n\n /* Compute partition of previous and next anchors */\n const partition$ = watchElementSize(document.body)\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n\n /* Build index to map anchor paths to vertical offsets */\n switchMap(body => defer(() => {\n let path: HTMLAnchorElement[] = []\n return of([...table].reduce((index, [anchor, target]) => {\n while (path.length) {\n const last = table.get(path[path.length - 1])!\n if (last.tagName >= target.tagName) {\n path.pop()\n } else {\n break\n }\n }\n\n /* If the current anchor is hidden, continue with its parent */\n let offset = target.offsetTop\n while (!offset && target.parentElement) {\n target = target.parentElement\n offset = target.offsetTop\n }\n\n /* Map reversed anchor path to vertical offset */\n return index.set(\n [...path = [...path, anchor]].reverse(),\n offset\n )\n }, new Map()))\n })\n .pipe(\n\n /* Sort index by vertical offset (see https://bit.ly/30z6QSO) */\n map(index => new Map([...index].sort(([, a], [, b]) => a - b))),\n combineLatestWith(adjust$),\n\n /* Re-compute partition when viewport offset changes */\n switchMap(([index, adjust]) => viewport$\n .pipe(\n scan(([prev, next], { offset: { y }, size }) => {\n const last = y + size.height >= Math.floor(body.height)\n\n /* Look forward */\n while (next.length) {\n const [, offset] = next[0]\n if (offset - adjust < y || last) {\n prev = [...prev, next.shift()!]\n } else {\n break\n }\n }\n\n /* Look backward */\n while (prev.length) {\n const [, offset] = prev[prev.length - 1]\n if (offset - adjust >= y && !last) {\n next = [prev.pop()!, ...next]\n } else {\n break\n }\n }\n\n /* Return partition */\n return [prev, next]\n }, [[], [...index]]),\n distinctUntilChanged((a, b) => (\n a[0] === b[0] &&\n a[1] === b[1]\n ))\n )\n )\n )\n )\n )\n\n /* Compute and return anchor list migrations */\n return partition$\n .pipe(\n map(([prev, next]) => ({\n prev: prev.map(([path]) => path),\n next: next.map(([path]) => path)\n })),\n\n /* Extract anchor list migrations */\n startWith({ prev: [], next: [] }),\n bufferCount(2, 1),\n map(([a, b]) => {\n\n /* Moving down */\n if (a.prev.length < b.prev.length) {\n return {\n prev: b.prev.slice(Math.max(0, a.prev.length - 1), b.prev.length),\n next: []\n }\n\n /* Moving up */\n } else {\n return {\n prev: b.prev.slice(-1),\n next: b.next.slice(0, b.next.length - a.next.length)\n }\n }\n })\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount table of contents\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents component observable\n */\nexport function mountTableOfContents(\n el: HTMLElement, { viewport$, header$, target$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ prev, next }) => {\n\n /* Look forward */\n for (const [anchor] of next) {\n anchor.removeAttribute(\"data-md-state\")\n anchor.classList.remove(\n \"md-nav__link--active\"\n )\n }\n\n /* Look backward */\n for (const [index, [anchor]] of prev.entries()) {\n anchor.setAttribute(\"data-md-state\", \"blur\")\n anchor.classList.toggle(\n \"md-nav__link--active\",\n index === prev.length - 1\n )\n }\n })\n\n /* Set up anchor tracking, if enabled */\n if (feature(\"navigation.tracking\"))\n viewport$\n .pipe(\n takeUntil(push$.pipe(takeLast(1))),\n distinctUntilKeyChanged(\"offset\"),\n debounceTime(250),\n skip(1),\n takeUntil(target$.pipe(skip(1))),\n repeat({ delay: 250 }),\n withLatestFrom(push$)\n )\n .subscribe(([, { prev }]) => {\n const url = getLocation()\n\n /* Set hash fragment to active anchor */\n const anchor = prev[prev.length - 1]\n if (anchor && anchor.length) {\n const [active] = anchor\n const { hash } = new URL(active.href)\n if (url.hash !== hash) {\n url.hash = hash\n history.replaceState({}, \"\", `${url}`)\n }\n\n /* Reset anchor when at the top */\n } else {\n url.hash = \"\"\n history.replaceState({}, \"\", `${url}`)\n }\n })\n\n /* Create and return component */\n return watchTableOfContents(el, { viewport$, header$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n endWith,\n finalize,\n map,\n repeat,\n skip,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { Viewport } from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Back-to-top button\n */\nexport interface BackToTop {\n hidden: boolean /* Back-to-top button is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch back-to-top\n *\n * @param _el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top observable\n */\nexport function watchBackToTop(\n _el: HTMLElement, { viewport$, main$, target$ }: WatchOptions\n): Observable {\n\n /* Compute direction */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => a > b && b > 0),\n distinctUntilChanged()\n )\n\n /* Compute whether main area is active */\n const active$ = main$\n .pipe(\n map(({ active }) => active)\n )\n\n /* Compute threshold for hiding */\n return combineLatest([active$, direction$])\n .pipe(\n map(([active, direction]) => !(active && direction)),\n distinctUntilChanged(),\n takeUntil(target$.pipe(skip(1))),\n endWith(true),\n repeat({ delay: 250 }),\n map(hidden => ({ hidden }))\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount back-to-top\n *\n * @param el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top component observable\n */\nexport function mountBackToTop(\n el: HTMLElement, { viewport$, header$, main$, target$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n if (hidden) {\n el.setAttribute(\"data-md-state\", \"hidden\")\n el.setAttribute(\"tabindex\", \"-1\")\n el.blur()\n } else {\n el.removeAttribute(\"data-md-state\")\n el.removeAttribute(\"tabindex\")\n }\n },\n\n /* Handle complete */\n complete() {\n el.style.top = \"\"\n el.setAttribute(\"data-md-state\", \"hidden\")\n el.removeAttribute(\"tabindex\")\n }\n })\n\n /* Watch header height */\n header$\n .pipe(\n takeUntil(push$.pipe(endWith(0), takeLast(1))),\n distinctUntilKeyChanged(\"height\")\n )\n .subscribe(({ height }) => {\n el.style.top = `${height + 16}px`\n })\n\n /* Create and return component */\n return watchBackToTop(el, { viewport$, main$, target$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n takeWhile,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch indeterminate checkboxes\n *\n * This function replaces the indeterminate \"pseudo state\" with the actual\n * indeterminate state, which is used to keep navigation always expanded.\n *\n * @param options - Options\n */\nexport function patchIndeterminate(\n { document$, tablet$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\n \"[data-md-state=indeterminate]\"\n )),\n tap(el => {\n el.indeterminate = true\n el.checked = false\n }),\n mergeMap(el => fromEvent(el, \"change\")\n .pipe(\n takeWhile(() => el.hasAttribute(\"data-md-state\")),\n map(() => el)\n )\n ),\n withLatestFrom(tablet$)\n )\n .subscribe(([el, tablet]) => {\n el.removeAttribute(\"data-md-state\")\n if (tablet)\n el.checked = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether the given device is an Apple device\n *\n * @returns Test result\n */\nfunction isAppleDevice(): boolean {\n return /(iPad|iPhone|iPod)/.test(navigator.userAgent)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all elements with `data-md-scrollfix` attributes\n *\n * This is a year-old patch which ensures that overflow scrolling works at the\n * top and bottom of containers on iOS by ensuring a `1px` scroll offset upon\n * the start of a touch event.\n *\n * @see https://bit.ly/2SCtAOO - Original source\n *\n * @param options - Options\n */\nexport function patchScrollfix(\n { document$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\"[data-md-scrollfix]\")),\n tap(el => el.removeAttribute(\"data-md-scrollfix\")),\n filter(isAppleDevice),\n mergeMap(el => fromEvent(el, \"touchstart\")\n .pipe(\n map(() => el)\n )\n )\n )\n .subscribe(el => {\n const top = el.scrollTop\n\n /* We're at the top of the container */\n if (top === 0) {\n el.scrollTop = 1\n\n /* We're at the bottom of the container */\n } else if (top + el.offsetHeight === el.scrollHeight) {\n el.scrollTop = top - 1\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n delay,\n map,\n of,\n switchMap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchToggle\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n viewport$: Observable /* Viewport observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch the document body to lock when search is open\n *\n * For mobile and tablet viewports, the search is rendered full screen, which\n * leads to scroll leaking when at the top or bottom of the search result. This\n * function locks the body when the search is in full screen mode, and restores\n * the scroll position when leaving.\n *\n * @param options - Options\n */\nexport function patchScrolllock(\n { viewport$, tablet$ }: PatchOptions\n): void {\n combineLatest([watchToggle(\"search\"), tablet$])\n .pipe(\n map(([active, tablet]) => active && !tablet),\n switchMap(active => of(active)\n .pipe(\n delay(active ? 400 : 100)\n )\n ),\n withLatestFrom(viewport$)\n )\n .subscribe(([active, { offset: { y }}]) => {\n if (active) {\n document.body.setAttribute(\"data-md-state\", \"lock\")\n document.body.style.top = `-${y}px`\n } else {\n const value = -1 * parseInt(document.body.style.top, 10)\n document.body.removeAttribute(\"data-md-state\")\n document.body.style.top = \"\"\n if (value)\n window.scrollTo(0, value)\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Polyfills\n * ------------------------------------------------------------------------- */\n\n/* Polyfill `Object.entries` */\nif (!Object.entries)\n Object.entries = function (obj: object) {\n const data: [string, string][] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push([key, obj[key]])\n\n /* Return entries */\n return data\n }\n\n/* Polyfill `Object.values` */\nif (!Object.values)\n Object.values = function (obj: object) {\n const data: string[] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push(obj[key])\n\n /* Return values */\n return data\n }\n\n/* ------------------------------------------------------------------------- */\n\n/* Polyfills for `Element` */\nif (typeof Element !== \"undefined\") {\n\n /* Polyfill `Element.scrollTo` */\n if (!Element.prototype.scrollTo)\n Element.prototype.scrollTo = function (\n x?: ScrollToOptions | number, y?: number\n ): void {\n if (typeof x === \"object\") {\n this.scrollLeft = x.left!\n this.scrollTop = x.top!\n } else {\n this.scrollLeft = x!\n this.scrollTop = y!\n }\n }\n\n /* Polyfill `Element.replaceWith` */\n if (!Element.prototype.replaceWith)\n Element.prototype.replaceWith = function (\n ...nodes: Array\n ): void {\n const parent = this.parentNode\n if (parent) {\n if (nodes.length === 0)\n parent.removeChild(this)\n\n /* Replace children and create text nodes */\n for (let i = nodes.length - 1; i >= 0; i--) {\n let node = nodes[i]\n if (typeof node !== \"object\")\n node = document.createTextNode(node)\n else if (node.parentNode)\n node.parentNode.removeChild(node)\n\n /* Replace child or insert before previous sibling */\n if (!i)\n parent.replaceChild(node, this)\n else\n parent.insertBefore(this.previousSibling!, node)\n }\n }\n }\n}\n"], + "mappings": "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", "names": [] } diff --git a/assets/stylesheets/main.3de6f41f.min.css b/assets/stylesheets/main.3de6f41f.min.css new file mode 100644 index 000000000..360d07480 --- /dev/null +++ b/assets/stylesheets/main.3de6f41f.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;-ms-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:transparent;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-default-fg-color:rgba(0,0,0,.87);--md-default-fg-color--light:rgba(0,0,0,.54);--md-default-fg-color--lighter:rgba(0,0,0,.32);--md-default-fg-color--lightest:rgba(0,0,0,.07);--md-default-bg-color:#fff;--md-default-bg-color--light:hsla(0,0%,100%,.7);--md-default-bg-color--lighter:hsla(0,0%,100%,.3);--md-default-bg-color--lightest:hsla(0,0%,100%,.12);--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:hsla(0,0%,100%,.7);--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7);--md-shadow-z1:0 0.2rem 0.5rem rgba(0,0,0,.05),0 0 0.05rem rgba(0,0,0,.1);--md-shadow-z2:0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25);--md-shadow-z3:0 0.2rem 0.5rem rgba(0,0,0,.2),0 0 0.05rem rgba(0,0,0,.35)}:root>*{--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-hl-color:rgba(255,255,0,.5);--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-mark-color:rgba(255,255,0,.5);--md-typeset-del-color:rgba(245,80,61,.15);--md-typeset-ins-color:rgba(11,213,112,.15);--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-table-color:rgba(0,0,0,.12);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-fg-color:#fff;--md-footer-fg-color--light:hsla(0,0%,100%,.7);--md-footer-fg-color--lighter:hsla(0,0%,100%,.3);--md-footer-bg-color:rgba(0,0,0,.87);--md-footer-bg-color--dark:rgba(0,0,0,.32)}.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}body,input{font-feature-settings:"kern","liga";font-family:var(--md-text-font-family)}body,code,input,kbd,pre{color:var(--md-typeset-color)}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;-moz-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}@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) transparent;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.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}@media (hover:none){.md-typeset abbr{position:relative}.md-typeset abbr[title]:-webkit-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}.md-typeset abbr[title]:-moz-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}[dir=ltr] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:is(:focus,:hover):after{left:0}[dir=rtl] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:is(:focus,:hover):after{right:0}.md-typeset abbr[title]:is(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}}.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}[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}[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}.md-typeset ol li :-webkit-any(ul,ol),.md-typeset ul li :-webkit-any(ul,ol){margin-bottom:.5em;margin-top:.5em}.md-typeset ol li :-moz-any(ul,ol),.md-typeset ul li :-moz-any(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset ol li :-webkit-any(ul,ol),[dir=ltr] .md-typeset ul li :-webkit-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :-moz-any(ul,ol),[dir=ltr] .md-typeset ul li :-moz-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :is(ul,ol),[dir=ltr] .md-typeset ul li :is(ul,ol){margin-left:.625em}[dir=rtl] .md-typeset ol li :-webkit-any(ul,ol),[dir=rtl] .md-typeset ul li :-webkit-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :-moz-any(ul,ol),[dir=rtl] .md-typeset ul li :-moz-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :is(ul,ol),[dir=rtl] .md-typeset ul li :is(ul,ol){margin-right:.625em}.md-typeset ol li :is(ul,ol),.md-typeset ul li :is(ul,ol){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{height:auto;max-width:100%}.md-typeset img[align=left],.md-typeset svg[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right],.md-typeset svg[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child,.md-typeset svg[align]:only-child{margin-top:0}.md-typeset img[src$="#gh-dark-mode-only"],.md-typeset img[src$="#only-dark"]{display:none}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.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]) :-webkit-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-moz-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :is(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-webkit-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-moz-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :is(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :is(th,td):not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :is(th,td):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]) th a{color:inherit}.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:rgba(0,0,0,.035);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.9375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius: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:var(--md-typeset-mark-color);color:var(--md-default-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}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.9375em){body[data-md-state=lock]{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;white-space:nowrap}.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:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:is(:focus,: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-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:-webkit-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:-moz-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:is(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.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{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{float:right;margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}[dir=rtl] .md-content__button{float:left}.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[data-md-state=open]{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-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{display:flex;justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__link{display:flex;flex-grow:0.01;outline-color:var(--md-accent-fg-color);overflow:hidden;padding-bottom:.4rem;padding-top:1.4rem;transition:opacity .25s}.md-footer__link:-webkit-any(:focus,:hover){opacity:.7}.md-footer__link:-moz-any(:focus,:hover){opacity:.7}.md-footer__link:is(:focus,:hover){opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.9375em){.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;line-height:2.4rem;max-width:calc(100% - 2.4rem);padding:0 1rem;position:relative}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;left:0;margin-top:-1rem;opacity:.7;padding:0 1rem;position:absolute;right:0}.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:-webkit-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:-moz-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:is(:focus,: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{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:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:is(:focus,: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:-webkit-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:-moz-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:is(:focus,: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 transparent,0 .2rem .4rem transparent;color:var(--md-primary-bg-color);left:0;position:-webkit-sticky;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[data-md-state=shadow]{box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2);transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header[data-md-state=hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,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.1875em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :is(img,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}.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-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem}[dir=ltr] .md-header__title{margin-left:1rem}[dir=rtl] .md-header__title{margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title[data-md-state=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[data-md-state=active] .md-header__topic{transform:translateX(1.25rem)}.md-header__title[data-md-state=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__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}}: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{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 :-webkit-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :is(img,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__item{padding:0 .6rem}[dir=ltr] .md-nav__item .md-nav__item{padding-right:0}[dir=rtl] .md-nav__item .md-nav__item{padding-left:0}.md-nav__link{align-items:center;cursor:pointer;display:flex;justify-content:space-between;margin-top:.625em;overflow:hidden;scroll-snap-align:start;text-overflow:ellipsis;transition:color 125ms}.md-nav__link[data-md-state=blur]{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active{color:var(--md-typeset-a-color)}.md-nav__item .md-nav__link--index [href]{width:100%}.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.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__link>*{cursor:pointer;display:flex}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.1875em){.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 :-webkit-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :-moz-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :is(.md-nav__title,.md-nav__item){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-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;-ms-scroll-snap-type:y mandatory;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);padding:0}.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:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}[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-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.9375em){.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.1875em){.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--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}}@media screen and (min-width:76.25em){.md-nav{transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon,.md-nav__toggle~.md-nav{display:none}.md-nav__toggle:-webkit-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:-moz-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:is(:checked,:indeterminate)~.md-nav{display:block}.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;pointer-events:none}.md-nav__item--section>.md-nav__link--index [href]{pointer-events:auto}.md-nav__item--section>.md-nav__link .md-nav__icon{display:none}.md-nav__item--section>.md-nav{display:block}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;float:right;height:.9rem;transition:background-color .25s,transform .25s;width:.9rem}[dir=rtl] .md-nav__icon{float:left;transform:rotate(180deg)}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.1rem;width:100%}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon,.md-nav__item--nested .md-nav__toggle:indeterminate~.md-nav__link .md-nav__icon{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__list>.md-nav__item--nested,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block;padding:0}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{font-weight:700;margin-top:0;padding:0 .6rem;pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link--index [href]{pointer-events:auto}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link .md-nav__icon{display:none}.md-nav--lifted .md-nav[data-md-level="1"]{display:block}[dir=ltr] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-right:.6rem}[dir=rtl] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-left:.6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[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}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}: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.9375em){[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:rgba(0,0,0,.54);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.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.9375em){[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.9375em){[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){.md-search__inner{float:right;padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}[dir=rtl] .md-search__inner{float:left}}@media screen and (min-width:60em) and (max-width:76.1875em){[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 transparent;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:rgba(0,0,0,.26);border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:hsla(0,0%,100%,.12)}}[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 rgba(0,0,0,.07);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:transparent;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::-moz-placeholder{-moz-transition:color .25s;transition:color .25s}.md-search__input::-ms-input-placeholder{-ms-transition:color .25s;transition:color .25s}.md-search__input::placeholder{transition:color .25s}.md-search__input::-moz-placeholder{color:var(--md-default-fg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}.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.9375em){.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::-moz-placeholder{color:var(--md-primary-bg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-primary-bg-color--light)}.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::-moz-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:var(--md-default-fg-color--light)}}.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.9375em){[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.9375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>*{margin-left:.2rem}[dir=rtl] .md-search__options>*{margin-right:.2rem}.md-search__options>*{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>:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>*{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>: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.9375em){.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.1875em){.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) transparent;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) transparent}.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}.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:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:is(:focus,: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{color:var(--md-typeset-a-color);cursor:pointer;display:block;font-size:.64rem;outline:none;padding:.75em .8rem;scroll-snap-align:start;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more summary{padding-left:2.2rem}[dir=rtl] .md-search-result__more summary{padding-right:2.2rem}}.md-search-result__more summary:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary::marker{display:none}.md-search-result__more summary::-webkit-details-marker{display:none}.md-search-result__more summary~*>*{opacity:.65}.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}}.md-search-result__article--document .md-search-result__title{font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}[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.9375em){.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-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__title{font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result__teaser{-webkit-box-orient:vertical;-webkit-line-clamp:2;color:var(--md-default-fg-color--light);display:-webkit-box;font-size:.64rem;line-height:1.6;margin:.5em 0;max-height:2rem;overflow:hidden;text-overflow:ellipsis}@media screen and (max-width:44.9375em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}.md-search-result__teaser mark{background-color:initial;text-decoration:underline}.md-search-result__terms{font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color)}.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:-webkit-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-webkit-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:-moz-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-moz-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:is(:focus-within,: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 transparent;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid transparent;border-right:.2rem solid transparent;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:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:is(:focus,: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:-webkit-sticky;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.1875em){[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;-ms-scroll-snap-type:none;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}}.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{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@media screen and (max-width:76.1875em){.md-overlay{background-color:rgba(0,0,0,.54);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%}}@-webkit-keyframes facts{0%{height:0}to{height:.65rem}}@keyframes facts{0%{height:0}to{height:.65rem}}@-webkit-keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}@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{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[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__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{font-size:.55rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0}[data-md-state=done] .md-source__facts{-webkit-animation:facts .25s ease-in;animation:facts .25s ease-in}.md-source__fact{display:inline-block}[data-md-state=done] .md-source__fact{-webkit-animation:fact .4s ease-out;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-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}[dir=ltr] .md-source__fact:nth-child(1n+2):before{margin-left:.4rem}[dir=rtl] .md-source__fact:nth-child(1n+2):before{margin-right:.4rem}.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-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);overflow:auto;width:100%}@media print{.md-tabs{display:none}}@media screen and (max-width:76.1875em){.md-tabs{display:none}}.md-tabs[data-md-state=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;list-style:none;margin:0;padding:0;white-space:nowrap}.md-tabs__item{display:inline-block;height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;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--active,.md-tabs__link:-webkit-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:-moz-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:is(:focus,:hover){color:inherit;opacity:1}.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[data-md-state=hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}.md-tags{margin-bottom:.75em}[dir=ltr] .md-tag{margin-right:.5em}[dir=rtl] .md-tag{margin-left:.5em}.md-tag{background:var(--md-default-fg-color--lightest);border-radius:.4rem;display:inline-block;font-size:.64rem;font-weight:700;line-height:1.6;margin-bottom:.5em;padding:.3125em .9375em}.md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-tag[href]:focus,.md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-tag{vertical-align:text-top}@-webkit-keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}@keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}:root{--md-tooltip-width:20rem}.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);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-height:0;max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,max-height 0ms .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}:focus-within>.md-tooltip{max-height:1000%;opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height .25s,z-index 0ms}.focus-visible>.md-tooltip{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{outline:none;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}.md-annotation:not([hidden]){display:inline-block;line-height:1.325}.md-annotation:focus-within>*{z-index:2}.md-annotation__inner{font-family:var(--md-text-font-family);top:calc(var(--md-tooltip-y) + 1.2ch)}:not(:focus-within)>.md-annotation__inner{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.md-annotation__index{color:#fff;cursor:pointer;margin:0 1ch;position:relative;transition:z-index .25s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0}.md-annotation__index:after{-webkit-animation:pulse 2s infinite;animation:pulse 2s infinite;background-color:var(--md-default-fg-color--lighter);border-radius:2ch;content:"";height:2.2ch;left:-.126em;margin:0 -.4ch;padding:0 .4ch;position:absolute;transition:color .25s,background-color .25s;width:calc(100% + 1.2ch);width:max(2.2ch,100% + 1.2ch);z-index:-1}@media (prefers-reduced-motion){.md-annotation__index:after{-webkit-animation:none;animation:none}}:-webkit-any(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:-moz-any(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:is(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:focus-within>.md-annotation__index:after{-webkit-animation:none;animation:none;transition:color .25s,background-color .25s}.md-annotation__index [data-md-annotation-id]{display:inline-block;line-height:90%}.md-annotation__index [data-md-annotation-id]:before{content:attr(data-md-annotation-id);display:inline-block;padding-bottom:.1em;transform:scale(1.15);transition:transform .4s cubic-bezier(.1,.7,.1,1);vertical-align:.065em}@media not print{.md-annotation__index [data-md-annotation-id]:before{content:"+"}:focus-within>.md-annotation__index [data-md-annotation-id]:before{transform:scale(1.25) rotate(45deg)}}:-webkit-any(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:-moz-any(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:is(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:focus-within>.md-annotation__index{-webkit-animation:none;animation:none;transition:none}[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);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[data-md-state=hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[data-md-state=hidden]{transform:translate(50%,.2rem)}.md-top:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:is(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@-webkit-keyframes hoverfix{0%{pointer-events:none}}@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-repeat:no-repeat;mask-repeat:no-repeat;width:.4rem}.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;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:-webkit-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-webkit-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:-moz-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-moz-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:is(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (pointer:coarse){.md-version:hover .md-version__list{-webkit-animation:hoverfix .25s forwards;animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{-webkit-animation:none;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:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:is(:focus,: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 :-webkit-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;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}.md-typeset :-moz-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;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}[dir=ltr] .md-typeset :-webkit-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition,details){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition,details){border-right-width:.2rem}.md-typeset :is(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;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}@media print{.md-typeset :-webkit-any(.admonition,details){box-shadow:none}.md-typeset :-moz-any(.admonition,details){box-shadow:none}.md-typeset :is(.admonition,details){box-shadow:none}}.md-typeset :-webkit-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :-moz-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :is(.admonition,details)>*{box-sizing:border-box}.md-typeset :-webkit-any(.admonition,details) :-webkit-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-moz-any(.admonition,details) :-moz-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :is(.admonition,details) :is(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-webkit-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :is(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-webkit-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :is(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-webkit-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :-moz-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :is(.admonition,details)>.tabbed-set:only-child{margin-top:0}html .md-typeset :-webkit-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :-moz-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :is(.admonition,details)>:last-child{margin-bottom:.6rem}.md-typeset :-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}.md-typeset :-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-right-width:.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}.md-typeset :is(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset :-webkit-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :-moz-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :is(.admonition-title,summary):last-child{margin-bottom:0}.md-typeset :-webkit-any(.admonition-title,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-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-moz-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain;position:absolute;top:.625em;width:1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :is(.admonition-title,summary):before{left:.8rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary):before{right:.8rem}.md-typeset :is(.admonition-title,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-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.note){border-color:#448aff}.md-typeset :-moz-any(.admonition,details):-moz-any(.note){border-color:#448aff}.md-typeset :is(.admonition,details):is(.note){border-color:#448aff}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :is(.note)>:is(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary):before{background-color:#448aff;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.note)>:is(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-moz-any(.admonition,details):-moz-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :is(.admonition,details):is(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary):before{background-color:#00b0ff;mask-image:var(--md-admonition-icon--abstract);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.info,.todo){border-color:#00b8d4}.md-typeset :-moz-any(.admonition,details):-moz-any(.info,.todo){border-color:#00b8d4}.md-typeset :is(.admonition,details):is(.info,.todo){border-color:#00b8d4}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary):before{background-color:#00b8d4;mask-image:var(--md-admonition-icon--info);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-moz-any(.admonition,details):-moz-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :is(.admonition,details):is(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary):before{background-color:#00bfa5;mask-image:var(--md-admonition-icon--tip);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.success,.check,.done){border-color:#00c853}.md-typeset :-moz-any(.admonition,details):-moz-any(.success,.check,.done){border-color:#00c853}.md-typeset :is(.admonition,details):is(.success,.check,.done){border-color:#00c853}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary):before{background-color:#00c853;mask-image:var(--md-admonition-icon--success);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :-moz-any(.admonition,details):-moz-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :is(.admonition,details):is(.question,.help,.faq){border-color:#64dd17}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary):before{background-color:#64dd17;mask-image:var(--md-admonition-icon--question);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-moz-any(.admonition,details):-moz-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :is(.admonition,details):is(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary):before{background-color:#ff9100;mask-image:var(--md-admonition-icon--warning);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-moz-any(.admonition,details):-moz-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :is(.admonition,details):is(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary):before{background-color:#ff5252;mask-image:var(--md-admonition-icon--failure);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.danger,.error){border-color:#ff1744}.md-typeset :-moz-any(.admonition,details):-moz-any(.danger,.error){border-color:#ff1744}.md-typeset :is(.admonition,details):is(.danger,.error){border-color:#ff1744}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary):before{background-color:#ff1744;mask-image:var(--md-admonition-icon--danger);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.bug){border-color:#f50057}.md-typeset :-moz-any(.admonition,details):-moz-any(.bug){border-color:#f50057}.md-typeset :is(.admonition,details):is(.bug){border-color:#f50057}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :is(.bug)>:is(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary):before{background-color:#f50057;mask-image:var(--md-admonition-icon--bug);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.bug)>:is(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.example){border-color:#7c4dff}.md-typeset :-moz-any(.admonition,details):-moz-any(.example){border-color:#7c4dff}.md-typeset :is(.admonition,details):is(.example){border-color:#7c4dff}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :is(.example)>:is(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary):before{background-color:#7c4dff;mask-image:var(--md-admonition-icon--example);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.example)>:is(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :-moz-any(.admonition,details):-moz-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :is(.admonition,details):is(.quote,.cite){border-color:#9e9e9e}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary):before{background-color:#9e9e9e;mask-image:var(--md-admonition-icon--quote);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}: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:-webkit-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:-moz-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:is(:hover,: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-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 :-webkit-any(:hover,:target)>.headerlink{opacity:1;-webkit-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :-moz-any(:hover,:target)>.headerlink{opacity:1;-moz-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :is(:hover,:target)>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:-webkit-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:-moz-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:is(:focus,: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 :-webkit-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :-moz-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :is(h1,h2,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.9375em){.md-typeset div.arithmatex{margin:0 -.8rem}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto;width:-webkit-min-content;width:-moz-min-content;width:min-content}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset :-webkit-any(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset :-moz-any(del,ins,.comment).critic{box-decoration-break:clone}.md-typeset :is(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{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}.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-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 :-webkit-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :is(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :is(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.highlight :-webkit-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :-moz-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :is(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight :-webkit-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-moz-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :is(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-webkit-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-moz-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :is(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-webkit-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-moz-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :is(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-webkit-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :is(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-moz-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :is(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-webkit-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-moz-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :is(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-webkit-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-moz-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :is(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-webkit-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :is(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-moz-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :is(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-webkit-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-moz-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :is(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-webkit-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-moz-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :is(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-webkit-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :-moz-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :is(.gd,.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);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:-webkit-sticky;position:sticky;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable :-webkit-any(tbody,td){display:block;padding:0}.highlighttable :-moz-any(tbody,td){display:block;padding:0}.highlighttable :is(tbody,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;-moz-user-select:none;-ms-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.9375em){.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:-webkit-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:-moz-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:is(:before,:after){-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}.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-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;-ms-scroll-snap-type:x proximity;scroll-snap-type:x proximity;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-accent-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,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 transparent;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-snap-align:start;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-accent-fg-color)}.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>.tabbed-set{margin:0}@media screen and (max-width:44.9375em){[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:""}}@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-accent-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-accent-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){background-color:var(--md-accent-fg-color--transparent)}.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-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)}: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)}.mermaid{line-height:normal;margin:1em 0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{float:left;margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}.md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}} \ No newline at end of file diff --git a/assets/stylesheets/main.3de6f41f.min.css.map b/assets/stylesheets/main.3de6f41f.min.css.map new file mode 100644 index 000000000..8db155711 --- /dev/null +++ b/assets/stylesheets/main.3de6f41f.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/assets/stylesheets/main/extensions/pymdownx/_keys.scss","../../../src/assets/stylesheets/main.scss","src/assets/stylesheets/main/_resets.scss","src/assets/stylesheets/main/_colors.scss","src/assets/stylesheets/main/_icons.scss","src/assets/stylesheets/main/_typeset.scss","src/assets/stylesheets/utilities/_break.scss","src/assets/stylesheets/main/layout/_banner.scss","src/assets/stylesheets/main/layout/_base.scss","src/assets/stylesheets/main/layout/_clipboard.scss","src/assets/stylesheets/main/layout/_content.scss","src/assets/stylesheets/main/layout/_dialog.scss","src/assets/stylesheets/main/layout/_footer.scss","src/assets/stylesheets/main/layout/_form.scss","src/assets/stylesheets/main/layout/_header.scss","src/assets/stylesheets/main/layout/_nav.scss","src/assets/stylesheets/main/layout/_search.scss","src/assets/stylesheets/main/layout/_select.scss","src/assets/stylesheets/main/layout/_sidebar.scss","src/assets/stylesheets/main/layout/_source.scss","src/assets/stylesheets/main/layout/_tabs.scss","src/assets/stylesheets/main/layout/_tag.scss","src/assets/stylesheets/main/layout/_tooltip.scss","src/assets/stylesheets/main/layout/_top.scss","src/assets/stylesheets/main/layout/_version.scss","src/assets/stylesheets/main/extensions/markdown/_admonition.scss","node_modules/material-design-color/material-color.scss","src/assets/stylesheets/main/extensions/markdown/_footnotes.scss","src/assets/stylesheets/main/extensions/markdown/_toc.scss","src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss","src/assets/stylesheets/main/extensions/pymdownx/_critic.scss","src/assets/stylesheets/main/extensions/pymdownx/_details.scss","src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss","src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss","src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss","src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss","src/assets/stylesheets/main/integrations/_mermaid.scss","src/assets/stylesheets/main/_modifiers.scss"],"names":[],"mappings":"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AGE,iBAAA,CADA,eAAA,CADA,a/BwmGN,C+BzmGI,sDAGE,iBAAA,CADA,eAAA,CADA,a/BwmGN,C+BzmGI,gDAGE,iBAAA,CADA,eAAA,CADA,a/BwmGN,CgC9mGE,gCACE,sChCinGJ,CgClnGE,6BACE,sChCinGJ,CgClnGE,uBACE,sChCinGJ,CgC9mGE,cACE,yChCgnGJ,CgCpmGE,4DACE,oChCsmGJ,CgCvmGE,yDACE,oChCsmGJ,CgCvmGE,mDACE,oChCsmGJ,CgC9lGE,6CACE,qChCgmGJ,CgCjmGE,0CACE,qChCgmGJ,CgCjmGE,oCACE,qChCgmGJ,CgCtlGE,oDACE,oChCwlGJ,CgCzlGE,iDACE,oChCwlGJ,CgCzlGE,2CACE,oChCwlGJ,CgC/kGE,gDACE,qChCilGJ,CgCllGE,6CACE,qChCilGJ,CgCllGE,uCACE,qChCilGJ,CgC5kGE,gCACE,kChC8kGJ,CgC/kGE,6BACE,kChC8kGJ,CgC/kGE,uBACE,kChC8kGJ,CgCxkGE,qCACE,sChC0kGJ,CgC3kGE,kCACE,sChC0kGJ,CgC3kGE,4BACE,sChC0kGJ,CgCnkGE,yCACE,sChCqkGJ,CgCtkGE,sCACE,sChCqkGJ,CgCtkGE,gCACE,sChCqkGJ,CgC9jGE,yCACE,qChCgkGJ,CgCjkGE,sCACE,qChCgkGJ,CgCjkGE,gCACE,qChCgkGJ,CgCvjGE,gDACE,qChCyjGJ,CgC1jGE,6CACE,qChCyjGJ,CgC1jGE,uCACE,qChCyjGJ,CgCjjGE,6CACE,sChCmjGJ,CgCpjGE,0CACE,sChCmjGJ,CgCpjGE,oCACE,sChCmjGJ,CgCxiGE,yDACE,qChC0iGJ,CgC3iGE,sDACE,qChC0iGJ,CgC3iGE,gDACE,qChC0iGJ,CgCriGE,iCAGE,mBAAA,CAFA,gBAAA,CACA,gBhCwiGJ,CgC1iGE,8BAGE,mBAAA,CAFA,gBAAA,CACA,gBhCwiGJ,CgC1iGE,wBAGE,mBAAA,CAFA,gBAAA,CACA,gBhCwiGJ,CgCpiGE,eACE,4ChCsiGJ,CgCniGE,eACE,4ChCqiGJ,CgCjiGE,gBAIE,wCAAA,CAHA,aAAA,CACA,wBAAA,CACA,wBhCoi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","file":"main.css"} \ No newline at end of file diff --git a/assets/stylesheets/main.8c5ef100.min.css b/assets/stylesheets/main.8c5ef100.min.css deleted file mode 100644 index 897156052..000000000 --- a/assets/stylesheets/main.8c5ef100.min.css +++ /dev/null @@ -1 +0,0 @@ -@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;-ms-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:transparent;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-default-fg-color:rgba(0,0,0,.87);--md-default-fg-color--light:rgba(0,0,0,.54);--md-default-fg-color--lighter:rgba(0,0,0,.32);--md-default-fg-color--lightest:rgba(0,0,0,.07);--md-default-bg-color:#fff;--md-default-bg-color--light:hsla(0,0%,100%,.7);--md-default-bg-color--lighter:hsla(0,0%,100%,.3);--md-default-bg-color--lightest:hsla(0,0%,100%,.12);--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:hsla(0,0%,100%,.7);--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7);--md-shadow-z1:0 0.2rem 0.5rem rgba(0,0,0,.05),0 0 0.05rem rgba(0,0,0,.1);--md-shadow-z2:0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25);--md-shadow-z3:0 0.2rem 0.5rem rgba(0,0,0,.2),0 0 0.05rem rgba(0,0,0,.35)}:root>*{--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-hl-color:rgba(255,255,0,.5);--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-mark-color:rgba(255,255,0,.5);--md-typeset-del-color:rgba(245,80,61,.15);--md-typeset-ins-color:rgba(11,213,112,.15);--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-table-color:rgba(0,0,0,.12);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-fg-color:#fff;--md-footer-fg-color--light:hsla(0,0%,100%,.7);--md-footer-fg-color--lighter:hsla(0,0%,100%,.3);--md-footer-bg-color:rgba(0,0,0,.87);--md-footer-bg-color--dark:rgba(0,0,0,.32)}.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}body,input{font-feature-settings:"kern","liga";font-family:var(--md-text-font-family)}body,code,input,kbd,pre{color:var(--md-typeset-color)}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}@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) transparent;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.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}@media (hover:none){.md-typeset abbr{position:relative}.md-typeset abbr[title]:-webkit-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}.md-typeset abbr[title]:-moz-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}[dir=ltr] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:is(:focus,:hover):after{left:0}[dir=rtl] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:is(:focus,:hover):after{right:0}.md-typeset abbr[title]:is(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}}.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}[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}[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}.md-typeset ol li :-webkit-any(ul,ol),.md-typeset ul li :-webkit-any(ul,ol){margin-bottom:.5em;margin-top:.5em}.md-typeset ol li :-moz-any(ul,ol),.md-typeset ul li :-moz-any(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset ol li :-webkit-any(ul,ol),[dir=ltr] .md-typeset ul li :-webkit-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :-moz-any(ul,ol),[dir=ltr] .md-typeset ul li :-moz-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :is(ul,ol),[dir=ltr] .md-typeset ul li :is(ul,ol){margin-left:.625em}[dir=rtl] .md-typeset ol li :-webkit-any(ul,ol),[dir=rtl] .md-typeset ul li :-webkit-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :-moz-any(ul,ol),[dir=rtl] .md-typeset ul li :-moz-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :is(ul,ol),[dir=rtl] .md-typeset ul li :is(ul,ol){margin-right:.625em}.md-typeset ol li :is(ul,ol),.md-typeset ul li :is(ul,ol){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{height:auto;max-width:100%}.md-typeset img[align=left],.md-typeset svg[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right],.md-typeset svg[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child,.md-typeset svg[align]:only-child{margin-top:0}.md-typeset img[src$="#only-dark"]{display:none}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.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]) :-webkit-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-moz-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :is(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-webkit-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-moz-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :is(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :is(th,td):not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :is(th,td):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]) th a{color:inherit}.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:rgba(0,0,0,.035);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.9375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius: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:var(--md-typeset-mark-color);color:var(--md-default-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}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.9375em){body[data-md-state=lock]{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;white-space:nowrap}.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:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:is(:focus,: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-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:-webkit-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:-moz-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:is(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.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{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{float:right;margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}[dir=rtl] .md-content__button{float:left}.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[data-md-state=open]{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-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{display:flex;justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__link{display:flex;flex-grow:0.01;outline-color:var(--md-accent-fg-color);overflow:hidden;padding-bottom:.4rem;padding-top:1.4rem;transition:opacity .25s}.md-footer__link:-webkit-any(:focus,:hover){opacity:.7}.md-footer__link:-moz-any(:focus,:hover){opacity:.7}.md-footer__link:is(:focus,:hover){opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.9375em){.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;line-height:2.4rem;max-width:calc(100% - 2.4rem);padding:0 1rem;position:relative}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;left:0;margin-top:-1rem;opacity:.7;padding:0 1rem;position:absolute;right:0}.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:-webkit-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:-moz-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:is(:focus,: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{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:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:is(:focus,: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:-webkit-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:-moz-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:is(:focus,: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 transparent,0 .2rem .4rem transparent;color:var(--md-primary-bg-color);left:0;position:-webkit-sticky;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[data-md-state=shadow]{box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2);transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header[data-md-state=hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,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.1875em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :is(img,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}.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-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem}[dir=ltr] .md-header__title{margin-left:1rem}[dir=rtl] .md-header__title{margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title[data-md-state=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[data-md-state=active] .md-header__topic{transform:translateX(1.25rem)}.md-header__title[data-md-state=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__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}}: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{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 :-webkit-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :is(img,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__item{padding:0 .6rem}[dir=ltr] .md-nav__item .md-nav__item{padding-right:0}[dir=rtl] .md-nav__item .md-nav__item{padding-left:0}.md-nav__link{align-items:center;cursor:pointer;display:flex;justify-content:space-between;margin-top:.625em;overflow:hidden;scroll-snap-align:start;text-overflow:ellipsis;transition:color 125ms}.md-nav__link[data-md-state=blur]{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active{color:var(--md-typeset-a-color)}.md-nav__item .md-nav__link--index [href]{width:100%}.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.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__link>*{cursor:pointer;display:flex}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.1875em){.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 :-webkit-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :-moz-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :is(.md-nav__title,.md-nav__item){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-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;-ms-scroll-snap-type:y mandatory;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);padding:0}.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:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}[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-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.9375em){.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.1875em){.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--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}}@media screen and (min-width:76.25em){.md-nav{transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon,.md-nav__toggle~.md-nav{display:none}.md-nav__toggle:-webkit-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:-moz-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:is(:checked,:indeterminate)~.md-nav{display:block}.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;pointer-events:none}.md-nav__item--section>.md-nav__link--index [href]{pointer-events:auto}.md-nav__item--section>.md-nav__link .md-nav__icon{display:none}.md-nav__item--section>.md-nav{display:block}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;float:right;height:.9rem;transition:background-color .25s,transform .25s;width:.9rem}[dir=rtl] .md-nav__icon{float:left;transform:rotate(180deg)}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.1rem;width:100%}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon,.md-nav__item--nested .md-nav__toggle:indeterminate~.md-nav__link .md-nav__icon{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__list>.md-nav__item--nested,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block;padding:0}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{font-weight:700;margin-top:0;padding:0 .6rem;pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link--index [href]{pointer-events:auto}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link .md-nav__icon{display:none}.md-nav--lifted .md-nav[data-md-level="1"]{display:block}[dir=ltr] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-right:.6rem}[dir=rtl] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-left:.6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[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}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}: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.9375em){[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:rgba(0,0,0,.54);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.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.9375em){[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.9375em){[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){.md-search__inner{float:right;padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}[dir=rtl] .md-search__inner{float:left}}@media screen and (min-width:60em) and (max-width:76.1875em){[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 transparent;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:rgba(0,0,0,.26);border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:hsla(0,0%,100%,.12)}}[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 rgba(0,0,0,.07);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:transparent;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::-moz-placeholder{-moz-transition:color .25s;transition:color .25s}.md-search__input::-ms-input-placeholder{-ms-transition:color .25s;transition:color .25s}.md-search__input::placeholder{transition:color .25s}.md-search__input::-moz-placeholder{color:var(--md-default-fg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}.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.9375em){.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::-moz-placeholder{color:var(--md-primary-bg-color--light)}.md-search__input::-ms-input-placeholder{color:var(--md-primary-bg-color--light)}.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::-moz-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::-ms-input-placeholder{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:var(--md-default-fg-color--light)}}.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.9375em){[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.9375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>*{margin-left:.2rem}[dir=rtl] .md-search__options>*{margin-right:.2rem}.md-search__options>*{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>:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>*{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>: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.9375em){.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.1875em){.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) transparent;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) transparent}.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}.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:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:is(:focus,: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{color:var(--md-typeset-a-color);cursor:pointer;display:block;font-size:.64rem;outline:none;padding:.75em .8rem;scroll-snap-align:start;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more summary{padding-left:2.2rem}[dir=rtl] .md-search-result__more summary{padding-right:2.2rem}}.md-search-result__more summary:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary::marker{display:none}.md-search-result__more summary::-webkit-details-marker{display:none}.md-search-result__more summary~*>*{opacity:.65}.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}}.md-search-result__article--document .md-search-result__title{font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}[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.9375em){.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-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__title{font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result__teaser{-webkit-box-orient:vertical;-webkit-line-clamp:2;color:var(--md-default-fg-color--light);display:-webkit-box;font-size:.64rem;line-height:1.6;margin:.5em 0;max-height:2rem;overflow:hidden;text-overflow:ellipsis}@media screen and (max-width:44.9375em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}.md-search-result__teaser mark{background-color:initial;text-decoration:underline}.md-search-result__terms{font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color)}.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:-webkit-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-webkit-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:-moz-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-moz-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:is(:focus-within,: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 transparent;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid transparent;border-right:.2rem solid transparent;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:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:is(:focus,: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:-webkit-sticky;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.1875em){[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;-ms-scroll-snap-type:none;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}}.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{-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin}.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) transparent}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@media screen and (max-width:76.1875em){.md-overlay{background-color:rgba(0,0,0,.54);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%}}@-webkit-keyframes facts{0%{height:0}to{height:.65rem}}@keyframes facts{0%{height:0}to{height:.65rem}}@-webkit-keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}@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{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[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__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{font-size:.55rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0}[data-md-state=done] .md-source__facts{-webkit-animation:facts .25s ease-in;animation:facts .25s ease-in}.md-source__fact{display:inline-block}[data-md-state=done] .md-source__fact{-webkit-animation:fact .4s ease-out;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-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}[dir=ltr] .md-source__fact:nth-child(1n+2):before{margin-left:.4rem}[dir=rtl] .md-source__fact:nth-child(1n+2):before{margin-right:.4rem}.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-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);overflow:auto;width:100%}@media print{.md-tabs{display:none}}@media screen and (max-width:76.1875em){.md-tabs{display:none}}.md-tabs[data-md-state=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;list-style:none;margin:0;padding:0;white-space:nowrap}.md-tabs__item{display:inline-block;height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;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--active,.md-tabs__link:-webkit-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:-moz-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:is(:focus,:hover){color:inherit;opacity:1}.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[data-md-state=hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}.md-tags{margin-bottom:.75em}[dir=ltr] .md-tag{margin-right:.5em}[dir=rtl] .md-tag{margin-left:.5em}.md-tag{background:var(--md-default-fg-color--lightest);border-radius:.4rem;display:inline-block;font-size:.64rem;font-weight:700;line-height:1.6;margin-bottom:.5em;padding:.3125em .9375em}.md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-tag[href]:focus,.md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-tag{vertical-align:text-top}@-webkit-keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}@keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest)}75%{box-shadow:0 0 0 .625em transparent}to{box-shadow:0 0 0 0 transparent}}:root{--md-tooltip-width:20rem}.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);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-height:0;max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,max-height 0ms .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}:focus-within>.md-tooltip{max-height:1000%;opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height .25s,z-index 0ms}.focus-visible>.md-tooltip{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{outline:none;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}.md-annotation:not([hidden]){display:inline-block;line-height:1.325}.md-annotation:focus-within>*{z-index:2}.md-annotation__inner{font-family:var(--md-text-font-family);top:calc(var(--md-tooltip-y) + 1.2ch)}:not(:focus-within)>.md-annotation__inner{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.md-annotation__index{color:#fff;cursor:pointer;margin:0 1ch;position:relative;transition:z-index .25s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0}.md-annotation__index:after{-webkit-animation:pulse 2s infinite;animation:pulse 2s infinite;background-color:var(--md-default-fg-color--lighter);border-radius:2ch;content:"";height:2.2ch;left:-.126em;margin:0 -.4ch;padding:0 .4ch;position:absolute;transition:color .25s,background-color .25s;width:calc(100% + 1.2ch);width:max(2.2ch,100% + 1.2ch);z-index:-1}@media (prefers-reduced-motion){.md-annotation__index:after{-webkit-animation:none;animation:none}}:-webkit-any(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:-moz-any(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:is(:focus-within,:hover)>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}:focus-within>.md-annotation__index:after{-webkit-animation:none;animation:none;transition:color .25s,background-color .25s}.md-annotation__index [data-md-annotation-id]{display:inline-block;line-height:90%}.md-annotation__index [data-md-annotation-id]:before{content:attr(data-md-annotation-id);display:inline-block;padding-bottom:.1em;transform:scale(1.15);transition:transform .4s cubic-bezier(.1,.7,.1,1);vertical-align:.065em}@media not print{.md-annotation__index [data-md-annotation-id]:before{content:"+"}:focus-within>.md-annotation__index [data-md-annotation-id]:before{transform:scale(1.25) rotate(45deg)}}:-webkit-any(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:-moz-any(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:is(:focus-within,:hover)>.md-annotation__index{color:var(--md-accent-bg-color)}:focus-within>.md-annotation__index{-webkit-animation:none;animation:none;transition:none}[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);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[data-md-state=hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[data-md-state=hidden]{transform:translate(50%,.2rem)}.md-top:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:is(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@-webkit-keyframes hoverfix{0%{pointer-events:none}}@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-repeat:no-repeat;mask-repeat:no-repeat;width:.4rem}.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;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:-webkit-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-webkit-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:-moz-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-moz-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:is(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (pointer:coarse){.md-version:hover .md-version__list{-webkit-animation:hoverfix .25s forwards;animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{-webkit-animation:none;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:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:is(:focus,: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 :-webkit-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;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}.md-typeset :-moz-any(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;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}[dir=ltr] .md-typeset :-webkit-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition,details){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition,details){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition,details){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition,details){border-right-width:.2rem}.md-typeset :is(.admonition,details){background-color:var(--md-admonition-bg-color);border:0 solid #448aff;border-radius:.1rem;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}@media print{.md-typeset :-webkit-any(.admonition,details){box-shadow:none}.md-typeset :-moz-any(.admonition,details){box-shadow:none}.md-typeset :is(.admonition,details){box-shadow:none}}.md-typeset :-webkit-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :-moz-any(.admonition,details)>*{box-sizing:border-box}.md-typeset :is(.admonition,details)>*{box-sizing:border-box}.md-typeset :-webkit-any(.admonition,details) :-webkit-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-moz-any(.admonition,details) :-moz-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :is(.admonition,details) :is(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset :-webkit-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :is(.admonition,details) .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset :-webkit-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-moz-any(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :is(.admonition,details) .md-typeset__table{padding:0 .6rem}.md-typeset :-webkit-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :-moz-any(.admonition,details)>.tabbed-set:only-child{margin-top:0}.md-typeset :is(.admonition,details)>.tabbed-set:only-child{margin-top:0}html .md-typeset :-webkit-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :-moz-any(.admonition,details)>:last-child{margin-bottom:.6rem}html .md-typeset :is(.admonition,details)>:last-child{margin-bottom:.6rem}.md-typeset :-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}.md-typeset :-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){margin-left:-.8rem;margin-right:-.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){margin-left:-.6rem;margin-right:-.8rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){padding-left:2.2rem;padding-right:.6rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){padding-left:.6rem;padding-right:2.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-left-width:.2rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-left-width:.2rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-right-width:.2rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-right-width:.2rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary){border-top-left-radius:.1rem}[dir=ltr] .md-typeset :is(.admonition-title,summary){border-top-left-radius:.1rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary){border-top-right-radius:.1rem}[dir=rtl] .md-typeset :is(.admonition-title,summary){border-top-right-radius:.1rem}.md-typeset :is(.admonition-title,summary){background-color:rgba(68,138,255,.1);border:none;font-weight:700;margin-bottom:0;margin-top:0;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset :-webkit-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :-moz-any(.admonition-title,summary):last-child{margin-bottom:0}html .md-typeset :is(.admonition-title,summary):last-child{margin-bottom:0}.md-typeset :-webkit-any(.admonition-title,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-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-moz-any(.admonition-title,summary):before{background-color:#448aff;content:"";height:1rem;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain;position:absolute;top:.625em;width:1rem}[dir=ltr] .md-typeset :-webkit-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :-moz-any(.admonition-title,summary):before{left:.8rem}[dir=ltr] .md-typeset :is(.admonition-title,summary):before{left:.8rem}[dir=rtl] .md-typeset :-webkit-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :-moz-any(.admonition-title,summary):before{right:.8rem}[dir=rtl] .md-typeset :is(.admonition-title,summary):before{right:.8rem}.md-typeset :is(.admonition-title,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-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.note){border-color:#448aff}.md-typeset :-moz-any(.admonition,details):-moz-any(.note){border-color:#448aff}.md-typeset :is(.admonition,details):is(.note){border-color:#448aff}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :is(.note)>:is(.admonition-title,summary){background-color:rgba(68,138,255,.1)}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary):before{background-color:#448aff;mask-image:var(--md-admonition-icon--note);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.note)>:is(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-moz-any(.admonition,details):-moz-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :is(.admonition,details):is(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary){background-color:rgba(0,176,255,.1)}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary):before{background-color:#00b0ff;mask-image:var(--md-admonition-icon--abstract);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.info,.todo){border-color:#00b8d4}.md-typeset :-moz-any(.admonition,details):-moz-any(.info,.todo){border-color:#00b8d4}.md-typeset :is(.admonition,details):is(.info,.todo){border-color:#00b8d4}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary){background-color:rgba(0,184,212,.1)}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary):before{background-color:#00b8d4;mask-image:var(--md-admonition-icon--info);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-moz-any(.admonition,details):-moz-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :is(.admonition,details):is(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary){background-color:rgba(0,191,165,.1)}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary):before{background-color:#00bfa5;mask-image:var(--md-admonition-icon--tip);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.success,.check,.done){border-color:#00c853}.md-typeset :-moz-any(.admonition,details):-moz-any(.success,.check,.done){border-color:#00c853}.md-typeset :is(.admonition,details):is(.success,.check,.done){border-color:#00c853}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary){background-color:rgba(0,200,83,.1)}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary):before{background-color:#00c853;mask-image:var(--md-admonition-icon--success);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :-moz-any(.admonition,details):-moz-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :is(.admonition,details):is(.question,.help,.faq){border-color:#64dd17}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary){background-color:rgba(100,221,23,.1)}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary):before{background-color:#64dd17;mask-image:var(--md-admonition-icon--question);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-moz-any(.admonition,details):-moz-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :is(.admonition,details):is(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary){background-color:rgba(255,145,0,.1)}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary):before{background-color:#ff9100;mask-image:var(--md-admonition-icon--warning);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-moz-any(.admonition,details):-moz-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :is(.admonition,details):is(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary){background-color:rgba(255,82,82,.1)}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary):before{background-color:#ff5252;mask-image:var(--md-admonition-icon--failure);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.danger,.error){border-color:#ff1744}.md-typeset :-moz-any(.admonition,details):-moz-any(.danger,.error){border-color:#ff1744}.md-typeset :is(.admonition,details):is(.danger,.error){border-color:#ff1744}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary){background-color:rgba(255,23,68,.1)}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary):before{background-color:#ff1744;mask-image:var(--md-admonition-icon--danger);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.bug){border-color:#f50057}.md-typeset :-moz-any(.admonition,details):-moz-any(.bug){border-color:#f50057}.md-typeset :is(.admonition,details):is(.bug){border-color:#f50057}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :is(.bug)>:is(.admonition-title,summary){background-color:rgba(245,0,87,.1)}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary):before{background-color:#f50057;mask-image:var(--md-admonition-icon--bug);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.bug)>:is(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.example){border-color:#7c4dff}.md-typeset :-moz-any(.admonition,details):-moz-any(.example){border-color:#7c4dff}.md-typeset :is(.admonition,details):is(.example){border-color:#7c4dff}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :is(.example)>:is(.admonition-title,summary){background-color:rgba(124,77,255,.1)}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary):before{background-color:#7c4dff;mask-image:var(--md-admonition-icon--example);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.example)>:is(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :-moz-any(.admonition,details):-moz-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :is(.admonition,details):is(.quote,.cite){border-color:#9e9e9e}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary){background-color:hsla(0,0%,62%,.1)}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary):before{background-color:#9e9e9e;mask-image:var(--md-admonition-icon--quote);mask-repeat:no-repeat;mask-size:contain}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}: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:-webkit-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:-moz-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:is(:hover,: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-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 :-webkit-any(:hover,:target)>.headerlink{opacity:1;-webkit-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :-moz-any(:hover,:target)>.headerlink{opacity:1;-moz-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :is(:hover,:target)>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:-webkit-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:-moz-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:is(:focus,: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 :-webkit-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :-moz-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :is(h1,h2,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.9375em){.md-typeset div.arithmatex{margin:0 -.8rem}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto;width:-webkit-min-content;width:-moz-min-content;width:min-content}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset :-webkit-any(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset :-moz-any(del,ins,.comment).critic{box-decoration-break:clone}.md-typeset :is(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{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}.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-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 :-webkit-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :is(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :is(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.highlight :-webkit-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :-moz-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :is(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight :-webkit-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-moz-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :is(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-webkit-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-moz-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :is(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-webkit-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-moz-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :is(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-webkit-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :is(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-moz-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :is(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-webkit-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-moz-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :is(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-webkit-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-moz-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :is(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-webkit-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :is(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-moz-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :is(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-webkit-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-moz-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :is(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-webkit-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-moz-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :is(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-webkit-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :-moz-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :is(.gd,.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);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:-webkit-sticky;position:sticky;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable :-webkit-any(tbody,td){display:block;padding:0}.highlighttable :-moz-any(tbody,td){display:block;padding:0}.highlighttable :is(tbody,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;-moz-user-select:none;-ms-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 code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset :-webkit-any(.highlight,.highlighttable)+.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 :-moz-any(.highlight,.highlighttable)+.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 :is(.highlight,.highlighttable)+.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 :-webkit-any(.highlight,.highlighttable)+.result:after{clear:both;content:"";display:block}.md-typeset :-moz-any(.highlight,.highlighttable)+.result:after{clear:both;content:"";display:block}.md-typeset :is(.highlight,.highlighttable)+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.9375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight .hll{margin:0 -.8rem;padding:0 .8rem}.md-content__inner>.highlight 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-content__inner>.highlighttable{border-radius:0;margin:1em -.8rem}.md-content__inner>.highlighttable .hll{margin:0 -.8rem;padding:0 .8rem}}.md-typeset .keys kbd:-webkit-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:-moz-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:is(:before,:after){-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}.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-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;-ms-scroll-snap-type:x proximity;scroll-snap-type:x proximity;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-accent-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,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 transparent;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-snap-align:start;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-accent-fg-color)}.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:first-child,.md-typeset .tabbed-block>.highlighttable:first-child,.md-typeset .tabbed-block>pre:first-child{margin:0}[dir=ltr] .md-typeset .tabbed-block>.highlight:first-child>pre:first-child>code,[dir=ltr] .md-typeset .tabbed-block>.highlighttable:first-child>code,[dir=ltr] .md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0}[dir=ltr] .md-typeset .tabbed-block>.highlight:first-child>pre:first-child>code,[dir=ltr] .md-typeset .tabbed-block>.highlighttable:first-child>code,[dir=ltr] .md-typeset .tabbed-block>pre:first-child>code,[dir=rtl] .md-typeset .tabbed-block>.highlight:first-child>pre:first-child>code,[dir=rtl] .md-typeset .tabbed-block>.highlighttable:first-child>code,[dir=rtl] .md-typeset .tabbed-block>pre:first-child>code{border-top-right-radius:0}[dir=ltr] .md-typeset .tabbed-block>.highlighttable:first-child .linenos,[dir=rtl] .md-typeset .tabbed-block>.highlight:first-child>pre:first-child>code,[dir=rtl] .md-typeset .tabbed-block>.highlighttable:first-child>code,[dir=rtl] .md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0}[dir=ltr] .md-typeset .tabbed-block>.highlighttable:first-child .linenos,[dir=rtl] .md-typeset .tabbed-block>.highlighttable:first-child .linenos{border-top-right-radius:0}[dir=rtl] .md-typeset .tabbed-block>.highlighttable:first-child .linenos{border-top-left-radius:0}.md-typeset .tabbed-block>.tabbed-set{margin:0}@media screen and (max-width:44.9375em){[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:""}}@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-accent-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-accent-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){background-color:var(--md-accent-fg-color--transparent)}.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-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)}: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)}.mermaid{line-height:normal;margin:1em 0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{float:left;margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}.md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}} \ No newline at end of file diff --git a/assets/stylesheets/main.8c5ef100.min.css.map b/assets/stylesheets/main.8c5ef100.min.css.map deleted file mode 100644 index 51603b280..000000000 --- a/assets/stylesheets/main.8c5ef100.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["src/assets/stylesheets/main/extensions/pymdownx/_keys.scss","../../../src/assets/stylesheets/main.scss","src/assets/stylesheets/main/_resets.scss","src/assets/stylesheets/main/_colors.scss","src/assets/stylesheets/main/_icons.scss","src/assets/stylesheets/main/_typeset.scss","src/assets/stylesheets/utilities/_break.scss","src/assets/stylesheets/main/layout/_banner.scss","src/assets/stylesheets/main/layout/_base.scss","src/assets/stylesheets/main/layout/_clipboard.scss","src/assets/stylesheets/main/layout/_content.scss","src/assets/stylesheets/main/layout/_dialog.scss","src/assets/stylesheets/main/layout/_footer.scss","src/assets/stylesheets/main/layout/_form.scss","src/assets/stylesheets/main/layout/_header.scss","src/assets/stylesheets/main/layout/_nav.scss","src/assets/stylesheets/main/layout/_search.scss","src/assets/stylesheets/main/layout/_select.scss","src/assets/stylesheets/main/layout/_sidebar.scss","src/assets/stylesheets/main/layout/_source.scss","src/assets/stylesheets/main/layout/_tabs.scss","src/assets/stylesheets/main/layout/_tag.scss","src/assets/stylesheets/main/layout/_tooltip.scss","src/assets/stylesheets/main/layout/_top.scss","src/assets/stylesheets/main/layout/_version.scss","src/assets/stylesheets/main/extensions/markdown/_admonition.scss","node_modules/material-design-color/material-color.scss","src/assets/stylesheets/main/extensions/markdown/_footnotes.scss","src/assets/stylesheets/main/extensions/markdown/_toc.scss","src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss","src/assets/stylesheets/main/extensions/pymdownx/_critic.scss","src/assets/stylesheets/main/extensions/pymdownx/_details.scss","src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss","src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss","src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss","src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss","src/assets/stylesheets/main/integrations/_mermaid.scss","src/assets/stylesheets/main/_modifiers.scss"],"names":[],"mappings":"AAgGM,gBC+vGN,CCn0GA,KAEE,6BAAA,CAAA,0BAAA,CAAA,yBAAA,CAAA,qBAAA,CADA,qBDzBF,CC8BA,iBAGE,kBD3BF,CC8BE,gCANF,iBAOI,yBDzBF,CACF,CC6BA,KACE,QD1BF,CC8BA,qBAIE,uCD3BF,CC+BA,EACE,aAAA,CACA,oBD5BF,CCgCA,GAME,QAAA,CAJA,kBAAA,CADA,aAAA,CAEA,aAAA,CAEA,gBAAA,CADA,SD3BF,CCiCA,MACE,aD9BF,CCkCA,QAEE,eD/BF,CCmCA,IACE,iBDhCF,CCoCA,MACE,uBAAA,CACA,gBDjCF,CCqCA,MAEE,eAAA,CACA,kBDlCF,CCsCA,OAKE,sBAAA,CACA,QAAA,CAFA,mBAAA,CADA,iBAAA,CAFA,QAAA,CACA,SD/BF,CCuCA,MACE,QAAA,CACA,YDpCF,CErDA,MAGE,qCAAA,CACA,4CAAA,CACA,8CAAA,CACA,+CAAA,CACA,0BAAA,CACA,+CAAA,CACA,iDAAA,CACA,mDAAA,CAGA,6BAAA,CACA,oCAAA,CACA,mCAAA,CACA,0BAAA,CACA,+CAAA,CAGA,4BAAA,CACA,qDAAA,CACA,yBAAA,CACA,8CAAA,CA0DA,yEAAA,CAKA,yEAAA,CAKA,yEFTF,CExDE,QAGE,0BAAA,CACA,0BAAA,CAGA,qCAAA,CACA,iCAAA,CACA,kCAAA,CACA,mCAAA,CACA,mCAAA,CACA,kCAAA,CACA,iCAAA,CACA,+CAAA,CACA,6DAAA,CACA,gEAAA,CACA,4DAAA,CACA,4DAAA,CACA,6DAAA,CAGA,6CAAA,CAGA,+CAAA,CAGA,0CAAA,CAGA,0CAAA,CACA,2CAAA,CAGA,8BAAA,CACA,kCAAA,CACA,qCAAA,CAGA,wCAAA,CAGA,mDAAA,CACA,mDAAA,CAGA,yBAAA,CACA,8CAAA,CACA,gDAAA,CACA,oCAAA,CACA,0CFsCJ,CGhHE,aAIE,iBAAA,CAHA,aAAA,CAEA,aAAA,CADA,YHqHJ,CI1HA,KACE,kCAAA,CACA,iCAAA,CAGA,uGAAA,CAKA,mFJ2HF,CIrHA,WAGE,mCAAA,CACA,sCJwHF,CIpHA,wBANE,6BJkIF,CI5HA,aAIE,4BAAA,CACA,sCJuHF,CI/GA,MACE,0NAAA,CACA,mNAAA,CACA,oNJkHF,CI3GA,YAGE,gCAAA,CAAA,kBAAA,CAFA,eAAA,CACA,eJ+GF,CI1GE,aAPF,YAQI,gBJ6GF,CACF,CI1GE,uGAME,iBAAA,CAAA,cJ4GJ,CIxGE,eAEE,uCAAA,CAEA,aAAA,CACA,eAAA,CAJA,iBJ+GJ,CItGE,8BAPE,eAAA,CAGA,qBJiHJ,CI7GE,eAGE,kBAAA,CACA,eAAA,CAHA,oBJ4GJ,CIpGE,eAGE,gBAAA,CADA,eAAA,CAGA,qBAAA,CADA,eAAA,CAHA,mBJ0GJ,CIlGE,kBACE,eJoGJ,CIhGE,eAEE,eAAA,CACA,qBAAA,CAFA,YJoGJ,CI9FE,8BAGE,uCAAA,CAEA,cAAA,CADA,eAAA,CAEA,qBAAA,CAJA,eJoGJ,CI5FE,eACE,wBJ8FJ,CI1FE,eAGE,+DAAA,CAFA,iBAAA,CACA,cJ6FJ,CIxFE,cACE,+BAAA,CACA,qBJ0FJ,CIvFI,mCAEE,sBJwFN,CIpFI,wCAEE,+BJqFN,CIlFM,kDACE,uDJoFR,CI/EI,mBACE,kBAAA,CACA,iCJiFN,CI7EI,4BACE,uCAAA,CACA,oBJ+EN,CI1EE,iDAGE,6BAAA,CACA,aJ4EJ,CIzEI,aAPF,iDAQI,oBJ8EJ,CACF,CI1EE,iBAIE,wCAAA,CACA,mBAAA,CACA,kCAAA,CAAA,0BAAA,CAJA,eAAA,CADA,uBAAA,CAEA,qBJ+EJ,CIzEI,qCAEE,uCAAA,CADA,YJ4EN,CItEE,gBAEE,iBAAA,CACA,eAAA,CAFA,iBJ0EJ,CIrEI,qBAQE,kCAAA,CAAA,0BAAA,CADA,eAAA,CANA,aAAA,CACA,QAAA,CAIA,uCAAA,CAFA,aAAA,CADA,oCAAA,CAQA,+DAAA,CADA,oBAAA,CADA,iBAAA,CAJA,iBJ6EN,CIpEM,2BACE,qDJsER,CIlEM,wCAEE,YAAA,CADA,WJqER,CIhEM,8CACE,oDJkER,CI/DQ,oDACE,0CJiEV,CI1DE,gBAOE,4CAAA,CACA,mBAAA,CACA,mKACE,CAPF,gCAAA,CAFA,oBAAA,CAGA,eAAA,CAFA,uBAAA,CAGA,uBAAA,CACA,qBJ+DJ,CIrDE,iBAGE,6CAAA,CACA,kCAAA,CAAA,0BAAA,CAHA,aAAA,CACA,qBJyDJ,CInDE,iBAEE,6DAAA,CACA,WAAA,CAFA,oBJuDJ,CIlDI,oBANF,iBAOI,iBJqDJ,CIlDI,yDAWE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAJA,gCAAA,CAKA,mBAAA,CAXA,oBAAA,CAOA,eAAA,CAHA,cAAA,CADA,aAAA,CADA,6BAAA,CAAA,qBAAA,CAGA,mBAAA,CAPA,iBAAA,CAGA,UJ8DN,CIlEI,sDAWE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAJA,gCAAA,CAKA,mBAAA,CAXA,oBAAA,CAOA,eAAA,CAHA,cAAA,CADA,aAAA,CADA,0BAAA,CAAA,qBAAA,CAGA,mBAAA,CAPA,iBAAA,CAGA,UJ8DN,CIlEI,mEAEE,MJgEN,CIlEI,gEAEE,MJgEN,CIlEI,0DAEE,MJgEN,CIlEI,mEAEE,OJgEN,CIlEI,gEAEE,OJgEN,CIlEI,0DAEE,OJgEN,CIlEI,gDAWE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAJA,gCAAA,CAKA,mBAAA,CAXA,oBAAA,CAOA,eAAA,CAHA,cAAA,CADA,aAAA,CADA,6BAAA,CAAA,0BAAA,CAAA,qBAAA,CAGA,mBAAA,CAPA,iBAAA,CAGA,UJ8DN,CACF,CI/CE,kBACE,WJiDJ,CI7CE,oDAEE,qBJ+CJ,CIjDE,oDAEE,sBJ+CJ,CI3CE,iCACE,kBJgDJ,CIjDE,iCACE,mBJgDJ,CIjDE,iCAIE,2DJ6CJ,CIjDE,iCAIE,4DJ6CJ,CIjDE,uBAGE,uCAAA,CADA,aAAA,CAAA,cJ+CJ,CIzCE,eACE,oBJ2CJ,CIvCE,kDAEE,kBJ0CJ,CI5CE,kDAEE,mBJ0CJ,CI5CE,8BAGE,SJyCJ,CItCI,0DACE,iBJyCN,CIrCI,oCACE,2BJwCN,CIrCM,0CACE,2BJwCR,CInCI,wDAEE,kBJsCN,CIxCI,wDAEE,mBJsCN,CIxCI,oCACE,kBJuCN,CInCM,kGAEE,aJuCR,CInCM,0DACE,eJsCR,CIlCM,4EACE,kBAAA,CAAA,eJsCR,CIvCM,sEACE,kBAAA,CAAA,eJsCR,CIvCM,gGAEE,kBJqCR,CIvCM,0FAEE,kBJqCR,CIvCM,8EAEE,kBJqCR,CIvCM,gGAEE,mBJqCR,CIvCM,0FAEE,mBJqCR,CIvCM,8EAEE,mBJqCR,CIvCM,0DACE,kBAAA,CAAA,eJsCR,CI/BE,yBAEE,mBJiCJ,CInCE,yBAEE,oBJiCJ,CInCE,eACE,mBAAA,CAAA,cJkCJ,CI7BE,gCAGE,WAAA,CADA,cJgCJ,CI5BI,wDAEE,oBJ+BN,CI3BI,0DAEE,oBJ8BN,CI1BI,oEACE,YJ6BN,CIxBE,mCACE,YJ0BJ,CItBE,mBACE,iBAAA,CAGA,eAAA,CADA,cAAA,CAEA,iBAAA,CAHA,yBAAA,CAAA,sBAAA,CAAA,iBJ2BJ,CIrBI,uBACE,aJuBN,CIlBE,uBAGE,iBAAA,CADA,eAAA,CADA,eJsBJ,CIhBE,mBACE,cJkBJ,CIdE,+BAKE,2CAAA,CACA,iDAAA,CACA,mBAAA,CANA,oBAAA,CAGA,gBAAA,CAFA,cAAA,CACA,aAAA,CAKA,iBJgBJ,CIbI,aAXF,+BAYI,aJgBJ,CACF,CIXI,iCACE,gBJaN,CINM,gEACE,YJQR,CITM,6DACE,YJQR,CITM,uDACE,YJQR,CIJM,+DACE,eJMR,CIPM,4DACE,eJMR,CIPM,sDACE,eJMR,CIDI,gEACE,eJGN,CIJI,6DACE,eJGN,CIJI,uDACE,eJGN,CIAM,0EACE,gBJER,CIHM,uEACE,gBJER,CIHM,iEACE,gBJER,CIGI,kCAGE,eAAA,CAFA,cAAA,CACA,sBAAA,CAEA,kBJDN,CIIM,oCACE,aJFR,CIOI,kCAGE,qDAAA,CAFA,sBAAA,CACA,kBJJN,CISI,wCACE,iCJPN,CIUM,8CACE,iCAAA,CACA,sDJRR,CIaI,iCACE,iBJXN,CIgBE,wCACE,cJdJ,CIiBI,wDAIE,gBJTN,CIKI,wDAIE,iBJTN,CIKI,8CAUE,UAAA,CATA,oBAAA,CAEA,YAAA,CAGA,oDAAA,CAAA,4CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CACA,iCAAA,CAJA,0BAAA,CAHA,WJPN,CImBI,oDACE,oDJjBN,CIqBI,mEACE,kDAAA,CACA,yDAAA,CAAA,iDJnBN,CIuBI,oEACE,kDAAA,CACA,0DAAA,CAAA,kDJrBN,CI0BE,wBACE,iBAAA,CACA,eAAA,CACA,iBJxBJ,CI4BE,mBACE,oBAAA,CACA,kBAAA,CACA,eJ1BJ,CI6BI,aANF,mBAOI,aJ1BJ,CACF,CI6BI,8BACE,aAAA,CAEA,QAAA,CACA,eAAA,CAFA,UJzBN,CKhWI,wCDwYF,uBACE,iBJpCF,CIuCE,4BACE,eJrCJ,CACF,CMliBA,WAGE,0CAAA,CADA,+BAAA,CADA,aNsiBF,CMjiBE,aANF,WAOI,YNoiBF,CACF,CMjiBE,oBAEE,uCAAA,CADA,gCNoiBJ,CM/hBE,kBAGE,eAAA,CAFA,iBAAA,CACA,eNkiBJ,COrjBA,KASE,cAAA,CARA,WAAA,CACA,iBPyjBF,CKrZI,oCEtKJ,KAaI,gBPkjBF,CACF,CK1ZI,oCEtKJ,KAkBI,cPkjBF,CACF,CO7iBA,KASE,2CAAA,CAPA,YAAA,CACA,qBAAA,CAKA,eAAA,CAHA,eAAA,CAJA,iBAAA,CAGA,UPmjBF,CO3iBE,aAZF,KAaI,aP8iBF,CACF,CK3ZI,wCEhJF,yBAII,cP2iBJ,CACF,COliBA,SAEE,gBAAA,CAAA,iBAAA,CADA,ePsiBF,COjiBA,cACE,YAAA,CACA,qBAAA,CACA,WPoiBF,COjiBE,aANF,cAOI,aPoiBF,CACF,COhiBA,SACE,WPmiBF,COhiBE,gBACE,YAAA,CACA,WAAA,CACA,iBPkiBJ,CO7hBA,aACE,eAAA,CAEA,sBAAA,CADA,kBPiiBF,COvhBA,WACE,YP0hBF,COrhBA,WAGE,QAAA,CACA,SAAA,CAHA,iBAAA,CACA,OP0hBF,COrhBE,uCACE,aPuhBJ,COnhBE,+BAEE,uCAAA,CADA,kBPshBJ,COhhBA,SASE,2CAAA,CACA,mBAAA,CAHA,gCAAA,CACA,gBAAA,CAHA,YAAA,CAQA,SAAA,CAFA,uCAAA,CALA,mBAAA,CALA,cAAA,CAWA,2BAAA,CARA,UP0hBF,CO9gBE,eAGE,SAAA,CADA,uBAAA,CAEA,oEACE,CAJF,UPmhBJ,COrgBA,MACE,WPwgBF,CQlqBA,MACE,+PRoqBF,CQ9pBA,cAQE,mBAAA,CADA,0CAAA,CAIA,cAAA,CALA,YAAA,CAGA,uCAAA,CACA,oBAAA,CATA,iBAAA,CAEA,UAAA,CADA,QAAA,CAUA,qBAAA,CAPA,WAAA,CADA,SRyqBF,CQ9pBE,aAfF,cAgBI,YRiqBF,CACF,CQ9pBE,kCAEE,uCAAA,CADA,YRiqBJ,CQ5pBE,qBACE,uCR8pBJ,CQ1pBE,yCACE,+BR4pBJ,CQ7pBE,sCACE,+BR4pBJ,CQ7pBE,gCACE,+BR4pBJ,CQvpBE,oBAKE,6BAAA,CAIA,UAAA,CARA,aAAA,CAEA,cAAA,CACA,aAAA,CAEA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CANA,aRgqBJ,CQrpBE,sBACE,cRupBJ,CQppBI,2BACE,2CRspBN,CQhpBI,sDAEE,uDAAA,CADA,+BRmpBN,CQppBI,mDAEE,uDAAA,CADA,+BRmpBN,CQppBI,6CAEE,uDAAA,CADA,+BRmpBN,CSxtBA,YACE,WAAA,CAIA,WTwtBF,CSrtBE,mBACE,qBAAA,CACA,iBTutBJ,CK3jBI,sCItJE,4EACE,kBTotBN,CShtBI,0JACE,mBTktBN,CSntBI,8EACE,kBTktBN,CACF,CS7sBI,0BAGE,UAAA,CAFA,aAAA,CACA,YTgtBN,CS3sBI,+BACE,eT6sBN,CSvsBE,8BAGE,iBT0sBJ,CS7sBE,8BAGE,kBT0sBJ,CS7sBE,oBACE,WAAA,CACA,cAAA,CAEA,STysBJ,CStsBI,aAPF,oBAQI,YTysBJ,CACF,CStsBI,8BACE,UTwsBN,CSpsBI,gCACE,yCTssBN,CSlsBI,wBACE,cAAA,CACA,kBTosBN,CSjsBM,kCACE,oBTmsBR,CUzwBA,qBAEE,WVuxBF,CUzxBA,qBAEE,UVuxBF,CUzxBA,WAOE,2CAAA,CACA,mBAAA,CALA,YAAA,CAMA,8BAAA,CAJA,iBAAA,CAMA,SAAA,CALA,mBAAA,CASA,mBAAA,CAdA,cAAA,CASA,0BAAA,CAEA,wCACE,CATF,SVqxBF,CUvwBE,aAlBF,WAmBI,YV0wBF,CACF,CUvwBE,+BAEE,SAAA,CAIA,mBAAA,CALA,uBAAA,CAEA,kEV0wBJ,CUnwBE,kBACE,gCAAA,CACA,eVqwBJ,CWxyBA,WAEE,0CAAA,CADA,+BX4yBF,CWxyBE,aALF,WAMI,YX2yBF,CACF,CWxyBE,kBACE,YAAA,CACA,6BAAA,CAEA,aAAA,CADA,aX2yBJ,CWtyBE,iBACE,YAAA,CAKA,cAAA,CAIA,uCAAA,CADA,eAAA,CADA,oBAAA,CADA,kBAAA,CAIA,uBXoyBJ,CWjyBI,4CACE,UXmyBN,CWpyBI,yCACE,UXmyBN,CWpyBI,mCACE,UXmyBN,CW/xBI,+BACE,oBXiyBN,CK9oBI,wCMzII,yCACE,YX0xBR,CACF,CWrxBI,iCACE,gBXwxBN,CWzxBI,iCACE,iBXwxBN,CWzxBI,uBAEE,gBXuxBN,CWpxBM,iCACE,eXsxBR,CWhxBE,kBAEE,WAAA,CAGA,eAAA,CACA,kBAAA,CAHA,6BAAA,CACA,cAAA,CAHA,iBXuxBJ,CW9wBE,mBACE,YAAA,CACA,aXgxBJ,CW5wBE,sBAKE,gBAAA,CAHA,MAAA,CACA,gBAAA,CAGA,UAAA,CAFA,cAAA,CAHA,iBAAA,CACA,OXkxBJ,CWzwBA,gBACE,gDX4wBF,CWzwBE,uBACE,YAAA,CACA,cAAA,CACA,6BAAA,CACA,aX2wBJ,CWvwBE,kCACE,sCXywBJ,CWtwBI,6DACE,+BXwwBN,CWzwBI,0DACE,+BXwwBN,CWzwBI,oDACE,+BXwwBN,CWhwBA,cAIE,wCAAA,CACA,gBAAA,CAHA,iBAAA,CACA,eAAA,CAFA,UXuwBF,CKztBI,mCM/CJ,cASI,UXmwBF,CACF,CW/vBE,yBACE,sCXiwBJ,CW1vBA,WACE,cAAA,CACA,qBX6vBF,CKtuBI,mCMzBJ,WAMI,eX6vBF,CACF,CW1vBE,iBACE,oBAAA,CAEA,aAAA,CACA,iBAAA,CAFA,YX8vBJ,CWzvBI,wBACE,eX2vBN,CWvvBI,qBAGE,iBAAA,CAFA,gBAAA,CACA,mBX0vBN,CY55BE,uBAKE,kBAAA,CACA,mBAAA,CAHA,gCAAA,CAIA,cAAA,CANA,oBAAA,CAGA,eAAA,CAFA,kBAAA,CAMA,gEZ+5BJ,CYz5BI,gCAEE,2CAAA,CACA,uCAAA,CAFA,gCZ65BN,CYv5BI,kDAEE,0CAAA,CACA,sCAAA,CAFA,+BZ25BN,CY55BI,+CAEE,0CAAA,CACA,sCAAA,CAFA,+BZ25BN,CY55BI,yCAEE,0CAAA,CACA,sCAAA,CAFA,+BZ25BN,CYp5BE,gCAKE,4BZy5BJ,CY95BE,gEAME,6BZw5BJ,CY95BE,gCAME,4BZw5BJ,CY95BE,sBAIE,6DAAA,CAGA,8BAAA,CAJA,eAAA,CAFA,aAAA,CACA,eAAA,CAMA,sCZs5BJ,CYj5BI,iDACE,6CAAA,CACA,8BZm5BN,CYr5BI,8CACE,6CAAA,CACA,8BZm5BN,CYr5BI,wCACE,6CAAA,CACA,8BZm5BN,CY/4BI,+BACE,UZi5BN,Cap8BA,WAME,2CAAA,CAGA,0DACE,CALF,gCAAA,CAFA,MAAA,CAFA,uBAAA,CAAA,eAAA,CAEA,OAAA,CADA,KAAA,CAEA,Sb08BF,Cah8BE,aAdF,WAeI,Ybm8BF,CACF,Cah8BE,iCACE,gEACE,CAEF,kEbg8BJ,Ca17BE,iCACE,2BAAA,CACA,iEb47BJ,Cat7BE,kBAEE,kBAAA,CADA,YAAA,CAEA,ebw7BJ,Cap7BE,mBAKE,kBAAA,CAGA,cAAA,CALA,YAAA,CAIA,uCAAA,CAHA,aAAA,CAHA,iBAAA,CAQA,uBAAA,CAHA,qBAAA,CAJA,Sb67BJ,Can7BI,yBACE,Ubq7BN,Caj7BI,iCACE,oBbm7BN,Ca/6BI,uCAEE,uCAAA,CADA,Ybk7BN,Ca76BI,2BACE,YAAA,CACA,ab+6BN,CKj0BI,wCQhHA,2BAMI,Yb+6BN,CACF,Ca56BM,iDAIE,iBAAA,CAHA,aAAA,CAEA,aAAA,CADA,Ubg7BR,Cal7BM,8CAIE,iBAAA,CAHA,aAAA,CAEA,aAAA,CADA,Ubg7BR,Cal7BM,wCAIE,iBAAA,CAHA,aAAA,CAEA,aAAA,CADA,Ubg7BR,CK/1BI,mCQ1EA,iCAII,Yby6BN,CACF,Cat6BM,wCACE,Ybw6BR,Cap6BM,+CACE,oBbs6BR,CK12BI,sCQvDA,iCAII,Ybi6BN,CACF,Ca55BE,kBAEE,YAAA,CACA,cAAA,CAFA,iBAAA,CAGA,8Db85BJ,Caz5BI,oCAGE,SAAA,CAIA,mBAAA,CALA,6BAAA,CAEA,8DACE,CAJF,Ub+5BN,Cat5BM,8CACE,8Bbw5BR,Can5BI,8BACE,ebq5BN,Cah5BE,4BAGE,kBbq5BJ,Cax5BE,4BAGE,iBbq5BJ,Cax5BE,4BAIE,gBbo5BJ,Cax5BE,4BAIE,iBbo5BJ,Cax5BE,kBACE,WAAA,CAIA,eAAA,CAHA,aAAA,CAIA,kBbk5BJ,Ca/4BI,0DAGE,SAAA,CAIA,mBAAA,CALA,8BAAA,CAEA,8DACE,CAJF,Ubq5BN,Ca54BM,oEACE,6Bb84BR,Ca14BM,4EAGE,SAAA,CAIA,mBAAA,CALA,uBAAA,CAEA,8DACE,CAJF,Sbg5BR,Car4BI,uCAGE,WAAA,CAFA,iBAAA,CACA,Ubw4BN,Cal4BE,mBACE,YAAA,CACA,aAAA,CACA,cAAA,CAEA,+CACE,CAFF,kBbq4BJ,Ca/3BI,8DACE,WAAA,CACA,SAAA,CACA,oCbi4BN,Ca13BE,mBACE,Yb43BJ,CK/6BI,mCQkDF,6BAQI,gBb43BJ,Cap4BA,6BAQI,iBb43BJ,Cap4BA,mBAKI,aAAA,CAEA,iBAAA,CADA,ab83BJ,CACF,CKv7BI,sCQkDF,6BAaI,kBb43BJ,Caz4BA,6BAaI,mBb43BJ,CACF,CclmCA,MACE,0MAAA,CACA,gMAAA,CACA,yNdqmCF,Cc/lCA,QACE,eAAA,CACA,edkmCF,Cc/lCE,eACE,aAAA,CAGA,eAAA,CADA,eAAA,CADA,eAAA,CAGA,sBdimCJ,Cc9lCI,+BACE,YdgmCN,Cc7lCM,mCAEE,WAAA,CADA,UdgmCR,CcxlCQ,6DAME,iBAAA,CALA,aAAA,CAGA,aAAA,CADA,cAAA,CAEA,kBAAA,CAHA,Ud8lCV,CchmCQ,0DAME,iBAAA,CALA,aAAA,CAGA,aAAA,CADA,cAAA,CAEA,kBAAA,CAHA,Ud8lCV,CchmCQ,oDAME,iBAAA,CALA,aAAA,CAGA,aAAA,CADA,cAAA,CAEA,kBAAA,CAHA,Ud8lCV,CcnlCE,cAGE,eAAA,CAFA,QAAA,CACA,SdslCJ,CcjlCE,cACE,edmlCJ,CchlCI,sCACE,edklCN,CcnlCI,sCACE,cdklCN,Cc7kCE,cAEE,kBAAA,CAKA,cAAA,CANA,YAAA,CAEA,6BAAA,CACA,iBAAA,CACA,eAAA,CAIA,uBAAA,CAHA,sBAAA,CAEA,sBdglCJ,Cc5kCI,kCACE,uCd8kCN,Cc1kCI,oCACE,+Bd4kCN,CcxkCI,0CACE,Ud0kCN,CctkCI,yCACE,+BdwkCN,CczkCI,sCACE,+BdwkCN,CczkCI,gCACE,+BdwkCN,CcpkCI,4BACE,uCAAA,CACA,oBdskCN,CclkCI,0CACE,YdokCN,CcjkCM,yDAKE,6BAAA,CAJA,aAAA,CAEA,WAAA,CACA,qCAAA,CAAA,6BAAA,CAFA,UdskCR,Cc/jCM,kDACE,YdikCR,Cc5jCI,gBAEE,cAAA,CADA,Yd+jCN,CczjCE,cACE,ad2jCJ,CcvjCE,gBACE,YdyjCJ,CKvgCI,wCS3CA,0CASE,2CAAA,CAHA,YAAA,CACA,qBAAA,CACA,WAAA,CAJA,MAAA,CAFA,iBAAA,CAEA,OAAA,CADA,KAAA,CAEA,SdwjCJ,Cc7iCI,4DACE,eAAA,CACA,ed+iCN,CcjjCI,yDACE,eAAA,CACA,ed+iCN,CcjjCI,mDACE,eAAA,CACA,ed+iCN,Cc3iCI,gCAOE,qDAAA,CAHA,uCAAA,CAIA,cAAA,CANA,aAAA,CAGA,kBAAA,CAFA,wBAAA,CAFA,iBAAA,CAKA,kBd+iCN,Cc1iCM,wDAGE,UdgjCR,CcnjCM,wDAGE,WdgjCR,CcnjCM,8CAIE,aAAA,CAEA,aAAA,CACA,YAAA,CANA,iBAAA,CACA,SAAA,CAGA,Yd8iCR,CcziCQ,oDAIE,6BAAA,CAIA,UAAA,CAPA,aAAA,CAEA,WAAA,CAEA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CALA,UdijCV,CctiCM,8CAEE,2CAAA,CACA,gEACE,CAHF,eAAA,CAIA,gCAAA,CAAA,4BAAA,CACA,kBduiCR,CcpiCQ,2DACE,YdsiCV,CcjiCM,8CAGE,2CAAA,CAFA,gCAAA,CACA,edoiCR,Cc/hCM,yCAIE,aAAA,CADA,UAAA,CAEA,YAAA,CACA,aAAA,CALA,iBAAA,CAEA,WAAA,CADA,SdqiCR,Cc5hCI,+BACE,Md8hCN,Cc1hCI,+BAEE,4DAAA,CADA,Sd6hCN,CczhCM,qDACE,+Bd2hCR,CcxhCQ,gFACE,+Bd0hCV,Cc3hCQ,6EACE,+Bd0hCV,Cc3hCQ,uEACE,+Bd0hCV,CcphCI,+BACE,YAAA,CACA,mBdshCN,CcnhCM,uDAGE,mBdshCR,CczhCM,uDAGE,kBdshCR,CczhCM,6CAIE,gBAAA,CAFA,aAAA,CADA,YdwhCR,CclhCQ,mDAIE,6BAAA,CAIA,UAAA,CAPA,aAAA,CAEA,WAAA,CAEA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CALA,Ud0hCV,Cc3gCM,+CACE,mBd6gCR,CcrgCM,4CAEE,wBAAA,CADA,edwgCR,CcpgCQ,oEACE,mBdsgCV,CcvgCQ,oEACE,oBdsgCV,CclgCQ,4EACE,iBdogCV,CcrgCQ,4EACE,kBdogCV,CchgCQ,oFACE,mBdkgCV,CcngCQ,oFACE,oBdkgCV,Cc9/BQ,4FACE,mBdggCV,CcjgCQ,4FACE,oBdggCV,Ccz/BE,mBACE,wBd2/BJ,Ccv/BE,wBACE,YAAA,CAEA,SAAA,CADA,0BAAA,CAEA,oEdy/BJ,Ccp/BI,kCACE,2Bds/BN,Ccj/BE,gCAEE,SAAA,CADA,uBAAA,CAEA,qEdm/BJ,Cc9+BI,8CAEE,kCAAA,CAAA,0Bd++BN,CACF,CKnpCI,wCS4KA,0CACE,Yd0+BJ,Ccv+BI,yDACE,Udy+BN,Ccr+BI,wDACE,Ydu+BN,Ccn+BI,kDACE,Ydq+BN,Cch+BE,gBAIE,iDAAA,CADA,gCAAA,CAFA,aAAA,CACA,edo+BJ,CACF,CKhtCM,6DSqPF,6CACE,Yd89BJ,Cc39BI,4DACE,Ud69BN,Ccz9BI,2DACE,Yd29BN,Ccv9BI,qDACE,Ydy9BN,CACF,CKxsCI,mCS0PE,6CACE,uBdi9BN,Cc78BI,gDACE,Yd+8BN,CACF,CKhtCI,sCS7JJ,QAoaI,oDd68BF,Ccv8BI,8CACE,uBdy8BN,Cc/7BE,sEACE,Ydo8BJ,Cch8BE,6DACE,adk8BJ,Ccn8BE,0DACE,adk8BJ,Ccn8BE,oDACE,adk8BJ,Cc97BE,6CACE,Ydg8BJ,Cc57BE,uBACE,aAAA,CACA,ed87BJ,Cc37BI,kCACE,ed67BN,Ccz7BI,qCACE,eAAA,CACA,mBd27BN,Ccx7BM,mDACE,mBd07BR,Cct7BM,mDACE,Ydw7BR,Ccn7BI,+BACE,adq7BN,Ccl7BM,2DACE,Sdo7BR,Cc96BE,cAIE,kBAAA,CAHA,WAAA,CAEA,YAAA,CAEA,+CACE,CAJF,Wdm7BJ,Cc36BI,wBACE,UAAA,CACA,wBd66BN,Ccz6BI,oBACE,uDd26BN,Ccv6BI,oBAKE,6BAAA,CAIA,UAAA,CARA,oBAAA,CAEA,WAAA,CAGA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CAJA,qBAAA,CAFA,Udg7BN,Ccr6BI,0JAEE,uBds6BN,Ccx5BI,+HACE,Yd85BN,Cc35BM,oDACE,aAAA,CACA,Sd65BR,Cc15BQ,kEAGE,eAAA,CAFA,YAAA,CACA,eAAA,CAEA,mBd45BV,Ccz5BU,gFACE,mBd25BZ,Ccv5BU,gFACE,Ydy5BZ,Ccj5BI,2CACE,adm5BN,Cch5BM,iFACE,mBdk5BR,Ccn5BM,iFACE,kBdk5BR,Ccz4BI,mFACE,ed24BN,Ccx4BM,iGACE,Sd04BR,Ccr4BI,qFAGE,mDdu4BN,Cc14BI,qFAGE,oDdu4BN,Cc14BI,2EACE,aAAA,CACA,oBdw4BN,Ccp4BM,0FACE,Yds4BR,CACF,Cex+CA,MACE,igBf2+CF,Cer+CA,WACE,iBfw+CF,CK10CI,mCU/JJ,WAKI,efw+CF,CACF,Cer+CE,kBACE,Yfu+CJ,Cen+CE,oBAEE,SAAA,CADA,Sfs+CJ,CKn0CI,wCUpKF,8BAQI,Yf6+CJ,Cer/CA,8BAQI,af6+CJ,Cer/CA,oBAYI,2CAAA,CACA,kBAAA,CAHA,WAAA,CACA,eAAA,CAOA,mBAAA,CAZA,iBAAA,CACA,SAAA,CAOA,uBAAA,CACA,4CACE,CAPF,Uf4+CJ,Ceh+CI,+DACE,SAAA,CACA,oCfk+CN,CACF,CKz2CI,mCUjJF,8BAiCI,Mfo+CJ,CergDA,8BAiCI,Ofo+CJ,CergDA,oBAoCI,gCAAA,CACA,cAAA,CAFA,QAAA,CAJA,cAAA,CACA,KAAA,CAMA,sDACE,CALF,Ofm+CJ,Cez9CI,+DAME,YAAA,CACA,SAAA,CACA,4CACE,CARF,Uf89CN,CACF,CKx2CI,wCUxGA,+DAII,mBfg9CN,CACF,CKt5CM,6DU/DF,+DASI,mBfg9CN,CACF,CK35CM,6DU/DF,+DAcI,mBfg9CN,CACF,Ce38CE,kBAEE,kCAAA,CAAA,0Bf48CJ,CK13CI,wCUpFF,4BAQI,Mfm9CJ,Ce39CA,4BAQI,Ofm9CJ,Ce39CA,kBAWI,QAAA,CAGA,SAAA,CAFA,eAAA,CANA,cAAA,CACA,KAAA,CAMA,wBAAA,CAEA,qGACE,CANF,OAAA,CADA,Sfk9CJ,Cer8CI,4BACE,yBfu8CN,Cen8CI,6DAEE,WAAA,CAEA,SAAA,CADA,uBAAA,CAEA,sGACE,CALF,Ufy8CN,CACF,CKr6CI,mCUjEF,kBA2CI,WAAA,CAEA,eAAA,CAHA,iBAAA,CAIA,8CAAA,CAFA,afk8CJ,Ce77CI,4BACE,Uf+7CN,CACF,CKv8CM,6DUYF,6DAII,af27CN,CACF,CKt7CI,sCUVA,6DASI,af27CN,CACF,Cet7CE,iBAIE,2CAAA,CACA,gCAAA,CAFA,aAAA,CAFA,iBAAA,CAKA,2CACE,CALF,Sf47CJ,CKn8CI,mCUKF,iBAaI,gCAAA,CACA,mBAAA,CAFA,afw7CJ,Cen7CI,uBACE,oCfq7CN,CACF,Cej7CI,4DAEE,2CAAA,CACA,6BAAA,CACA,oCAAA,CAHA,gCfs7CN,Ce96CE,4BAKE,mBAAA,CAAA,oBfm7CJ,Cex7CE,4BAKE,mBAAA,CAAA,oBfm7CJ,Cex7CE,kBAQE,sBAAA,CAFA,eAAA,CAFA,WAAA,CAHA,iBAAA,CAMA,sBAAA,CAJA,UAAA,CADA,Sfs7CJ,Ce76CI,oCACE,0BAAA,CAAA,qBf+6CN,Ceh7CI,yCACE,yBAAA,CAAA,qBf+6CN,Ceh7CI,+BACE,qBf+6CN,Ce36CI,oCAEE,uCf46CN,Ce96CI,yCAEE,uCf46CN,Ce96CI,kEAEE,uCf46CN,Cex6CI,6BACE,Yf06CN,CKn9CI,wCUkBF,kBA8BI,eAAA,CADA,aAAA,CADA,Uf26CJ,CACF,CK7+CI,mCUqCF,4BAmCI,mBf26CJ,Ce98CA,4BAmCI,oBf26CJ,Ce98CA,kBAoCI,aAAA,CACA,efy6CJ,Cet6CI,oCACE,uCfw6CN,Cez6CI,yCACE,uCfw6CN,Cez6CI,+BACE,uCfw6CN,Cep6CI,mCACE,gCfs6CN,Cel6CI,6DACE,kBfo6CN,Cej6CM,+EAEE,uCfk6CR,Cep6CM,oFAEE,uCfk6CR,Cep6CM,wJAEE,uCfk6CR,CACF,Ce55CE,iBAIE,cAAA,CAHA,oBAAA,CAEA,aAAA,CAEA,kCACE,CAJF,Yfi6CJ,Cez5CI,uBACE,Uf25CN,Cev5CI,yCAGE,Uf05CN,Ce75CI,yCAGE,Wf05CN,Ce75CI,+BACE,iBAAA,CACA,SAAA,CAEA,Sfy5CN,Cet5CM,6CACE,oBfw5CR,CKhgDI,wCUgGA,yCAcI,Ufu5CN,Cer6CE,yCAcI,Wfu5CN,Cer6CE,+BAaI,Sfw5CN,Cep5CM,+CACE,Yfs5CR,CACF,CK5hDI,mCUmHA,+BAwBI,mBfq5CN,Cel5CM,8CACE,Yfo5CR,CACF,Ce94CE,8BAGE,Wfk5CJ,Cer5CE,8BAGE,Ufk5CJ,Cer5CE,oBAKE,mBAAA,CAJA,iBAAA,CACA,SAAA,CAEA,Sfi5CJ,CKxhDI,wCUmIF,8BAUI,Wfg5CJ,Ce15CA,8BAUI,Ufg5CJ,Ce15CA,oBASI,Sfi5CJ,CACF,Ce74CI,gCACE,iBfm5CN,Cep5CI,gCACE,kBfm5CN,Cep5CI,sBAEE,uCAAA,CAEA,SAAA,CADA,oBAAA,CAEA,+Df+4CN,Ce14CM,yCAEE,uCAAA,CADA,Yf64CR,Cex4CM,yFAGE,SAAA,CACA,mBAAA,CAFA,kBf24CR,Cet4CQ,8FACE,Ufw4CV,Cej4CE,8BAOE,mBAAA,CAAA,oBfw4CJ,Ce/4CE,8BAOE,mBAAA,CAAA,oBfw4CJ,Ce/4CE,oBAIE,kBAAA,CAIA,yCAAA,CALA,YAAA,CAMA,eAAA,CAHA,WAAA,CAKA,SAAA,CAVA,iBAAA,CACA,KAAA,CAUA,uBAAA,CAFA,kBAAA,CALA,Uf04CJ,CKllDI,mCUmMF,8BAgBI,mBfo4CJ,Cep5CA,8BAgBI,oBfo4CJ,Cep5CA,oBAiBI,efm4CJ,CACF,Ceh4CI,+DACE,SAAA,CACA,0Bfk4CN,Ce73CE,6BAKE,+Bfg4CJ,Cer4CE,0DAME,gCf+3CJ,Cer4CE,6BAME,+Bf+3CJ,Cer4CE,mBAIE,eAAA,CAHA,iBAAA,CAEA,UAAA,CADA,Sfm4CJ,CKjlDI,wCU4MF,mBAWI,QAAA,CADA,Ufg4CJ,CACF,CK1mDI,mCU+NF,mBAiBI,SAAA,CADA,UAAA,CAEA,sBf+3CJ,Ce53CI,8DACE,8BAAA,CACA,Sf83CN,CACF,Cez3CE,uBAKE,kCAAA,CAAA,0BAAA,CAFA,2CAAA,CAFA,WAAA,CACA,eAAA,CAOA,kBfu3CJ,Cep3CI,iEAZF,uBAaI,uBfu3CJ,CACF,CKvpDM,6DUkRJ,uBAkBI,afu3CJ,CACF,CKtoDI,sCU4PF,uBAuBI,afu3CJ,CACF,CK3oDI,mCU4PF,uBA4BI,YAAA,CAEA,+DAAA,CADA,oBfw3CJ,Cep3CI,kEACE,efs3CN,Cel3CI,6BACE,qDfo3CN,Ceh3CI,0CAEE,YAAA,CADA,Wfm3CN,Ce92CI,gDACE,oDfg3CN,Ce72CM,sDACE,0Cf+2CR,CACF,Cex2CA,kBACE,gCAAA,CACA,qBf22CF,Cex2CE,wBAKE,qDAAA,CAHA,uCAAA,CACA,gBAAA,CACA,kBAAA,CAHA,eAAA,CAKA,uBf02CJ,CK/qDI,mCU+TF,kCAUI,mBf02CJ,Cep3CA,kCAUI,oBf02CJ,CACF,Cet2CE,wBAGE,eAAA,CAFA,QAAA,CACA,Sfy2CJ,Cep2CE,wBACE,yDfs2CJ,Cen2CI,oCACE,efq2CN,Ceh2CE,wBACE,aAAA,CACA,YAAA,CAEA,uBAAA,CADA,gCfm2CJ,Ce/1CI,mDACE,uDfi2CN,Cel2CI,gDACE,uDfi2CN,Cel2CI,0CACE,uDfi2CN,Ce71CI,gDACE,mBf+1CN,Ce11CE,gCAGE,+BAAA,CAGA,cAAA,CALA,aAAA,CAGA,gBAAA,CACA,YAAA,CAHA,mBAAA,CAQA,uBAAA,CAHA,2Cf61CJ,CKrtDI,mCUiXF,0CAcI,mBf01CJ,Cex2CA,0CAcI,oBf01CJ,CACF,Cev1CI,2DAEE,uDAAA,CADA,+Bf01CN,Ce31CI,wDAEE,uDAAA,CADA,+Bf01CN,Ce31CI,kDAEE,uDAAA,CADA,+Bf01CN,Cer1CI,wCACE,Yfu1CN,Cel1CI,wDACE,Yfo1CN,Ceh1CI,oCACE,Wfk1CN,Ce70CE,2BAGE,eAAA,CADA,eAAA,CADA,iBfi1CJ,CK5uDI,mCU0ZF,qCAOI,mBf+0CJ,Cet1CA,qCAOI,oBf+0CJ,CACF,Cez0CM,8DAGE,eAAA,CADA,eAAA,CAEA,eAAA,CAHA,ef80CR,Cer0CE,kCAEE,Mf20CJ,Ce70CE,kCAEE,Of20CJ,Ce70CE,wBAME,uCAAA,CAFA,aAAA,CACA,YAAA,CAJA,iBAAA,CAEA,Yf00CJ,CK5uDI,wCU+ZF,wBAUI,Yfu0CJ,CACF,Cep0CI,8BAIE,6BAAA,CAIA,UAAA,CAPA,oBAAA,CAEA,WAAA,CAEA,+CAAA,CAAA,uCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CALA,Uf40CN,Cen0CM,wCACE,oBfq0CR,Ce/zCE,yBAGE,gBAAA,CADA,eAAA,CAEA,eAAA,CAHA,afo0CJ,Ce7zCE,0BASE,2BAAA,CACA,oBAAA,CALA,uCAAA,CAJA,mBAAA,CAKA,gBAAA,CACA,eAAA,CAJA,aAAA,CADA,eAAA,CAEA,eAAA,CAIA,sBfi0CJ,CKhxDI,wCUucF,0BAeI,oBAAA,CADA,efg0CJ,CACF,CK/zDM,6DUgfJ,0BAqBI,oBAAA,CADA,efg0CJ,CACF,Ce5zCI,+BAEE,wBAAA,CADA,yBf+zCN,CezzCE,yBAEE,gBAAA,CACA,iBAAA,CAFA,af6zCJ,CevzCE,uBAEE,wBAAA,CADA,+Bf0zCJ,CgBl+DA,WACE,iBAAA,CACA,ShBq+DF,CgBl+DE,kBAOE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAHA,gCAAA,CAHA,QAAA,CAEA,gBAAA,CADA,YAAA,CAOA,SAAA,CAVA,iBAAA,CACA,sBAAA,CAQA,mCAAA,CAEA,oEhBo+DJ,CgB99DI,+DACE,gBAAA,CAEA,SAAA,CADA,+BAAA,CAEA,sFACE,CADF,8EhBg+DN,CgBp+DI,4DACE,gBAAA,CAEA,SAAA,CADA,+BAAA,CAEA,mFACE,CADF,8EhBg+DN,CgBp+DI,sDACE,gBAAA,CAEA,SAAA,CADA,+BAAA,CAEA,8EhBg+DN,CgBz9DI,wBAUE,qCAAA,CAAA,8CAAA,CAFA,mCAAA,CAAA,oCAAA,CACA,YAAA,CAEA,UAAA,CANA,QAAA,CAFA,QAAA,CAIA,kBAAA,CADA,iBAAA,CALA,iBAAA,CACA,KAAA,CAEA,OhBk+DN,CgBt9DE,iBAOE,mBAAA,CAFA,eAAA,CACA,oBAAA,CAJA,QAAA,CADA,kBAAA,CAGA,aAAA,CADA,ShB49DJ,CgBp9DE,iBACE,kBhBs9DJ,CgBl9DE,2BAGE,kBAAA,CAAA,oBhBw9DJ,CgB39DE,2BAGE,mBAAA,CAAA,mBhBw9DJ,CgB39DE,iBAKE,cAAA,CAJA,aAAA,CAGA,YAAA,CAKA,uBAAA,CAHA,2CACE,CALF,UhBy9DJ,CgB/8DI,4CACE,+BhBi9DN,CgBl9DI,yCACE,+BhBi9DN,CgBl9DI,mCACE,+BhBi9DN,CgB78DI,uBACE,qDhB+8DN,CiBniEA,YAIE,qBAAA,CADA,aAAA,CAGA,gBAAA,CALA,uBAAA,CAAA,eAAA,CACA,UAAA,CAGA,ajBuiEF,CiBniEE,aATF,YAUI,YjBsiEF,CACF,CKx3DI,wCYxKA,+BAGE,ajB0iEJ,CiB7iEE,+BAGE,cjB0iEJ,CiB7iEE,qBAQE,2CAAA,CAHA,aAAA,CAEA,WAAA,CANA,cAAA,CACA,KAAA,CAOA,uBAAA,CACA,iEACE,CALF,aAAA,CAFA,SjByiEJ,CiB9hEI,mEACE,8BAAA,CACA,6BjBgiEN,CiB7hEM,6EACE,8BjB+hER,CiB1hEI,6CAEE,QAAA,CAAA,MAAA,CACA,QAAA,CAEA,eAAA,CAJA,iBAAA,CACA,OAAA,CAEA,yBAAA,CAAA,qBAAA,CAFA,KjB+hEN,CACF,CKv6DI,sCYtKJ,YAuDI,QjB0hEF,CiBvhEE,mBACE,WjByhEJ,CACF,CiBrhEE,uBACE,YAAA,CACA,OjBuhEJ,CKn7DI,mCYtGF,uBAMI,QjBuhEJ,CiBphEI,8BACE,WjBshEN,CiBlhEI,qCACE,ajBohEN,CiBhhEI,+CACE,kBjBkhEN,CACF,CiB7gEE,wBAIE,kCAAA,CAAA,0BAAA,CAHA,cAAA,CACA,eAAA,CAQA,+DAAA,CADA,oBjB2gEJ,CiBvgEI,8BACE,qDjBygEN,CiBrgEI,2CAEE,YAAA,CADA,WjBwgEN,CiBngEI,iDACE,oDjBqgEN,CiBlgEM,uDACE,0CjBogER,CKl8DI,wCYxDF,YAME,gCAAA,CADA,QAAA,CAEA,SAAA,CANA,cAAA,CACA,KAAA,CAMA,sDACE,CALF,OAAA,CADA,SjBmgEF,CiBx/DE,4CAEE,WAAA,CACA,SAAA,CACA,4CACE,CAJF,UjB6/DJ,CACF,CkB9oEA,yBACE,GACE,QlBgpEF,CkB7oEA,GACE,alB+oEF,CACF,CkBtpEA,iBACE,GACE,QlBgpEF,CkB7oEA,GACE,alB+oEF,CACF,CkB3oEA,wBACE,GAEE,SAAA,CADA,0BlB8oEF,CkB1oEA,IACE,SlB4oEF,CkBzoEA,GAEE,SAAA,CADA,uBlB4oEF,CACF,CkBxpEA,gBACE,GAEE,SAAA,CADA,0BlB8oEF,CkB1oEA,IACE,SlB4oEF,CkBzoEA,GAEE,SAAA,CADA,uBlB4oEF,CACF,CkBnoEA,MACE,mgBAAA,CACA,oiBAAA,CACA,0nBAAA,CACA,mhBlBqoEF,CkB/nEA,WAOE,kCAAA,CAAA,0BAAA,CANA,aAAA,CACA,gBAAA,CACA,eAAA,CAEA,uCAAA,CAGA,uBAAA,CAJA,kBlBqoEF,CkB9nEE,iBACE,UlBgoEJ,CkB5nEE,iBACE,oBAAA,CAEA,aAAA,CACA,qBAAA,CAFA,UlBgoEJ,CkB3nEI,+BAEE,iBlB6nEN,CkB/nEI,+BAEE,kBlB6nEN,CkB/nEI,qBACE,gBlB8nEN,CkBznEI,kDACE,iBlB4nEN,CkB7nEI,kDACE,kBlB4nEN,CkB7nEI,kDAEE,iBlB2nEN,CkB7nEI,kDAEE,kBlB2nEN,CkBtnEE,iCAGE,iBlB2nEJ,CkB9nEE,iCAGE,kBlB2nEJ,CkB9nEE,uBACE,oBAAA,CACA,6BAAA,CAEA,eAAA,CACA,sBAAA,CACA,qBlBwnEJ,CkBpnEE,kBAIE,gBAAA,CACA,oBAAA,CAJA,gBAAA,CAKA,WAAA,CAHA,eAAA,CADA,SlB0nEJ,CkBnnEI,uCACE,oCAAA,CAAA,4BlBqnEN,CkBhnEE,iBACE,oBlBknEJ,CkB/mEI,sCACE,mCAAA,CAAA,2BlBinEN,CkB7mEI,kCAIE,kBlBonEN,CkBxnEI,kCAIE,iBlBonEN,CkBxnEI,wBAME,6BAAA,CAGA,UAAA,CARA,oBAAA,CAEA,YAAA,CAIA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CAHA,uBAAA,CAHA,WlBsnEN,CkB3mEI,kDACE,iBlB6mEN,CkB9mEI,kDACE,kBlB6mEN,CkBzmEI,iCACE,gDAAA,CAAA,wClB2mEN,CkBvmEI,+BACE,8CAAA,CAAA,sClBymEN,CkBrmEI,+BACE,8CAAA,CAAA,sClBumEN,CkBnmEI,sCACE,qDAAA,CAAA,6ClBqmEN,CmBvvEA,SAIE,2CAAA,CADA,gCAAA,CADA,aAAA,CADA,UnB6vEF,CmBvvEE,aAPF,SAQI,YnB0vEF,CACF,CK1kEI,wCczLJ,SAaI,YnB0vEF,CACF,CmBvvEE,+BACE,mBnByvEJ,CmBrvEE,yBAEE,iBnB2vEJ,CmB7vEE,yBAEE,kBnB2vEJ,CmB7vEE,eAME,eAAA,CADA,eAAA,CAJA,QAAA,CAEA,SAAA,CACA,kBnByvEJ,CmBnvEE,eACE,oBAAA,CACA,aAAA,CACA,kBAAA,CAAA,mBnBqvEJ,CmBhvEE,eAOE,kCAAA,CAAA,0BAAA,CANA,aAAA,CAEA,eAAA,CADA,gBAAA,CAMA,UAAA,CAJA,uCAAA,CACA,oBAAA,CAIA,8DnBivEJ,CmB5uEI,iEAEE,aAAA,CACA,SnB6uEN,CmBhvEI,8DAEE,aAAA,CACA,SnB6uEN,CmBhvEI,wDAEE,aAAA,CACA,SnB6uEN,CmBxuEM,2CACE,qBnB0uER,CmB3uEM,2CACE,qBnB6uER,CmB9uEM,2CACE,qBnBgvER,CmBjvEM,2CACE,qBnBmvER,CmBpvEM,2CACE,oBnBsvER,CmBvvEM,2CACE,qBnByvER,CmB1vEM,2CACE,qBnB4vER,CmB7vEM,2CACE,qBnB+vER,CmBhwEM,4CACE,qBnBkwER,CmBnwEM,4CACE,oBnBqwER,CmBtwEM,4CACE,qBnBwwER,CmBzwEM,4CACE,qBnB2wER,CmB5wEM,4CACE,qBnB8wER,CmB/wEM,4CACE,qBnBixER,CmBlxEM,4CACE,oBnBoxER,CmB9wEI,8CAEE,SAAA,CADA,yBAAA,CAEA,wCnBgxEN,CoBx1EA,SACE,mBpB21EF,CoBv1EA,kBAEE,iBpBi2EF,CoBn2EA,kBAEE,gBpBi2EF,CoBn2EA,QAQE,+CAAA,CACA,mBAAA,CARA,oBAAA,CAKA,gBAAA,CADA,eAAA,CAEA,eAAA,CAJA,kBAAA,CACA,uBpB+1EF,CoBv1EE,cAGE,uCAAA,CAFA,aAAA,CACA,YAAA,CAEA,6CpBy1EJ,CoBp1EI,wCAGE,0CAAA,CADA,+BpBs1EN,CoBh1EE,aACE,uBpBk1EJ,CqBr3EA,yBACE,GACE,uDrBw3EF,CqBr3EA,IACE,mCrBu3EF,CqBp3EA,GACE,8BrBs3EF,CACF,CqBj4EA,iBACE,GACE,uDrBw3EF,CqBr3EA,IACE,mCrBu3EF,CqBp3EA,GACE,8BrBs3EF,CACF,CqB92EA,MACE,wBrBg3EF,CqB12EA,YA0BE,kCAAA,CAAA,0BAAA,CALA,2CAAA,CACA,mBAAA,CACA,8BAAA,CAHA,gCAAA,CAjBA,iJACE,CAeF,YAAA,CADA,8BAAA,CASA,SAAA,CA1BA,iBAAA,CACA,uBAAA,CAsBA,4BAAA,CAIA,2EACE,CAZF,6BAAA,CADA,SrBq3EF,CqBl2EE,0BACE,gBAAA,CAEA,SAAA,CADA,uBAAA,CAEA,2FrBo2EJ,CqB51EE,2BACE,sCrB81EJ,CqB11EE,mBAEE,gBAAA,CADA,arB61EJ,CqBz1EI,2CACE,YrB21EN,CqBv1EI,0CACE,erBy1EN,CqBj1EA,eAEE,YAAA,CADA,kBrBq1EF,CqBj1EE,yBACE,arBm1EJ,CqB/0EE,6BACE,oBAAA,CAGA,iBrB+0EJ,CqB30EE,8BACE,SrB60EJ,CqBz0EE,sBAEE,sCAAA,CADA,qCrB40EJ,CqBx0EI,0CAEE,mBAAA,CADA,wBAAA,CAAA,qBAAA,CAAA,oBAAA,CAAA,gBrB20EN,CqBr0EE,sBAIE,UAAA,CACA,cAAA,CAFA,YAAA,CAFA,iBAAA,CAKA,uBAAA,CACA,wBAAA,CAAA,qBAAA,CAAA,oBAAA,CAAA,gBAAA,CALA,SrB40EJ,CqBj0EI,4BAgBE,mCAAA,CAAA,2BAAA,CALA,oDAAA,CACA,iBAAA,CAKA,UAAA,CATA,YAAA,CANA,YAAA,CAOA,cAAA,CACA,cAAA,CATA,iBAAA,CAYA,2CACE,CARF,wBAAA,CACA,6BAAA,CAJA,UrB60EN,CqB5zEM,gCApBF,4BAqBI,sBAAA,CAAA,crB+zEN,CACF,CqB5zEM,+DACE,0CrB8zER,CqB/zEM,4DACE,0CrB8zER,CqB/zEM,sDACE,0CrB8zER,CqB1zEM,0CAIE,sBAAA,CAAA,cAAA,CAHA,2CrB6zER,CqBrzEI,8CACE,oBAAA,CACA,erBuzEN,CqBpzEM,qDAME,mCAAA,CALA,oBAAA,CACA,mBAAA,CAEA,qBAAA,CACA,iDAAA,CAFA,qBrByzER,CqBlzEQ,iBAVF,qDAWI,WrBqzER,CqBlzEQ,mEACE,mCrBozEV,CACF,CqB9yEI,yDACE,+BrBgzEN,CqBjzEI,sDACE,+BrBgzEN,CqBjzEI,gDACE,+BrBgzEN,CqB5yEI,oCAEE,sBAAA,CAAA,cAAA,CADA,erB+yEN,CsBxgFA,kBAIE,etBohFF,CsBxhFA,kBAIE,gBtBohFF,CsBxhFA,QAQE,2CAAA,CACA,oBAAA,CAEA,8BAAA,CALA,uCAAA,CACA,eAAA,CAGA,YAAA,CALA,mBAAA,CAJA,cAAA,CACA,UAAA,CAUA,yBAAA,CACA,mGACE,CAXF,StBqhFF,CsBpgFE,aApBF,QAqBI,YtBugFF,CACF,CsBpgFE,kBACE,wBtBsgFJ,CsBlgFE,8BAEE,SAAA,CAEA,mBAAA,CAHA,+BAAA,CAEA,uBtBqgFJ,CsBjgFI,wCACE,8BtBmgFN,CsB9/EE,mCAEE,0CAAA,CADA,+BtBigFJ,CsBlgFE,gCAEE,0CAAA,CADA,+BtBigFJ,CsBlgFE,0BAEE,0CAAA,CADA,+BtBigFJ,CsB5/EE,YACE,oBAAA,CACA,oBtB8/EJ,CuBjjFA,4BACE,GACE,mBvBojFF,CACF,CuBvjFA,oBACE,GACE,mBvBojFF,CACF,CuB5iFA,MACE,kiBvB8iFF,CuBxiFA,YACE,aAAA,CAEA,eAAA,CADA,avB4iFF,CuBxiFE,+BAOE,kBAAA,CAAA,kBvByiFJ,CuBhjFE,+BAOE,iBAAA,CAAA,mBvByiFJ,CuBhjFE,qBAQE,aAAA,CAEA,cAAA,CADA,YAAA,CARA,iBAAA,CAKA,UvB0iFJ,CuBniFI,qCAIE,iBvByiFN,CuB7iFI,qCAIE,kBvByiFN,CuB7iFI,2BAKE,6BAAA,CAGA,UAAA,CAPA,oBAAA,CAEA,YAAA,CAGA,yCAAA,CAAA,iCAAA,CACA,6BAAA,CAAA,qBAAA,CALA,WvB2iFN,CuBhiFE,kBAUE,2CAAA,CACA,mBAAA,CACA,8BAAA,CAJA,gCAAA,CACA,oBAAA,CAJA,kBAAA,CADA,YAAA,CASA,SAAA,CANA,aAAA,CADA,SAAA,CALA,iBAAA,CAgBA,gCAAA,CAAA,4BAAA,CAfA,UAAA,CAYA,+CACE,CAZF,SvB8iFJ,CuB7hFI,gEACE,gBAAA,CACA,SAAA,CACA,8CACE,CADF,sCvB+hFN,CuBliFI,6DACE,gBAAA,CACA,SAAA,CACA,2CACE,CADF,sCvB+hFN,CuBliFI,uDACE,gBAAA,CACA,SAAA,CACA,sCvB+hFN,CuBzhFI,wBAGE,oCACE,wCAAA,CAAA,gCvByhFN,CuBrhFI,2CACE,sBAAA,CAAA,cvBuhFN,CACF,CuBlhFE,kBACE,kBvBohFJ,CuBhhFE,4BAGE,kBAAA,CAAA,oBvBuhFJ,CuB1hFE,4BAGE,mBAAA,CAAA,mBvBuhFJ,CuB1hFE,kBAME,cAAA,CALA,aAAA,CAIA,YAAA,CAKA,uBAAA,CAHA,2CACE,CAJF,kBAAA,CAFA,UvBwhFJ,CuB7gFI,6CACE,+BvB+gFN,CuBhhFI,0CACE,+BvB+gFN,CuBhhFI,oCACE,+BvB+gFN,CuB3gFI,wBACE,qDvB6gFN,CwB5mFA,MAEI,2RAAA,CAAA,8WAAA,CAAA,sPAAA,CAAA,8xBAAA,CAAA,qNAAA,CAAA,gbAAA,CAAA,gMAAA,CAAA,+PAAA,CAAA,8KAAA,CAAA,0eAAA,CAAA,kUAAA,CAAA,gMxBqoFJ,CwBznFE,8CAOE,8CAAA,CACA,sBAAA,CAEA,mBAAA,CACA,8BAAA,CAPA,mCAAA,CAHA,iBAAA,CAIA,gBAAA,CAHA,iBAAA,CACA,eAAA,CAGA,uBxBioFJ,CwBvoFE,2CAOE,8CAAA,CACA,sBAAA,CAEA,mBAAA,CACA,8BAAA,CAPA,mCAAA,CAHA,iBAAA,CAIA,gBAAA,CAHA,iBAAA,CACA,eAAA,CAGA,uBxBioFJ,CwBvoFE,wDASE,uBxB8nFJ,CwBvoFE,qDASE,uBxB8nFJ,CwBvoFE,+CASE,uBxB8nFJ,CwBvoFE,wDASE,wBxB8nFJ,CwBvoFE,qDASE,wBxB8nFJ,CwBvoFE,+CASE,wBxB8nFJ,CwBvoFE,qCAOE,8CAAA,CACA,sBAAA,CAEA,mBAAA,CACA,8BAAA,CAPA,mCAAA,CAHA,iBAAA,CAIA,gBAAA,CAHA,iBAAA,CACA,eAAA,CAGA,uBxBioFJ,CwBznFI,aAdF,8CAeI,exB4nFJ,CwB3oFA,2CAeI,exB4nFJ,CwB3oFA,qCAeI,exB4nFJ,CACF,CwBxnFI,gDACE,qBxB0nFN,CwB3nFI,6CACE,qBxB0nFN,CwB3nFI,uCACE,qBxB0nFN,CwBtnFI,gFAEE,iBAAA,CADA,cxBynFN,CwB1nFI,0EAEE,iBAAA,CADA,cxBynFN,CwB1nFI,8DAEE,iBAAA,CADA,cxBynFN,CwBpnFI,sEACE,iBxBsnFN,CwBvnFI,mEACE,iBxBsnFN,CwBvnFI,6DACE,iBxBsnFN,CwBlnFI,iEACE,exBonFN,CwBrnFI,8DACE,exBonFN,CwBrnFI,wDACE,exBonFN,CwBhnFI,qEACE,YxBknFN,CwBnnFI,kEACE,YxBknFN,CwBnnFI,4DACE,YxBknFN,CwB9mFI,+DACE,mBxBgnFN,CwBjnFI,4DACE,mBxBgnFN,CwBjnFI,sDACE,mBxBgnFN,CwB3mFE,oDAOE,oCAAA,CACA,WAAA,CAFA,eAAA,CAJA,eAAA,CAAA,YAAA,CAEA,oBAAA,CAAA,iBAAA,CAHA,iBxBsnFJ,CwBvnFE,iDAOE,oCAAA,CACA,WAAA,CAFA,eAAA,CAJA,eAAA,CAAA,YAAA,CAEA,oBAAA,CAAA,iBAAA,CAHA,iBxBsnFJ,CwBvnFE,8DAGE,kBAAA,CAAA,mBxBonFJ,CwBvnFE,2DAGE,kBAAA,CAAA,mBxBonFJ,CwBvnFE,qDAGE,kBAAA,CAAA,mBxBonFJ,CwBvnFE,8DAGE,kBAAA,CAAA,mBxBonFJ,CwBvnFE,2DAGE,kBAAA,CAAA,mBxBonFJ,CwBvnFE,qDAGE,kBAAA,CAAA,mBxBonFJ,CwBvnFE,8DAKE,mBAAA,CAAA,mBxBknFJ,CwBvnFE,2DAKE,mBAAA,CAAA,mBxBknFJ,CwBvnFE,qDAKE,mBAAA,CAAA,mBxBknFJ,CwBvnFE,8DAKE,kBAAA,CAAA,oBxBknFJ,CwBvnFE,2DAKE,kBAAA,CAAA,oBxBknFJ,CwBvnFE,qDAKE,kBAAA,CAAA,oBxBknFJ,CwBvnFE,8DASE,uBxB8mFJ,CwBvnFE,2DASE,uBxB8mFJ,CwBvnFE,qDASE,uBxB8mFJ,CwBvnFE,8DASE,wBxB8mFJ,CwBvnFE,2DASE,wBxB8mFJ,CwBvnFE,qDASE,wBxB8mFJ,CwBvnFE,8DAUE,4BxB6mFJ,CwBvnFE,2DAUE,4BxB6mFJ,CwBvnFE,qDAUE,4BxB6mFJ,CwBvnFE,8DAUE,6BxB6mFJ,CwBvnFE,2DAUE,6BxB6mFJ,CwBvnFE,qDAUE,6BxB6mFJ,CwBvnFE,2CAOE,oCAAA,CACA,WAAA,CAFA,eAAA,CAJA,eAAA,CAAA,YAAA,CAEA,oBAAA,CAAA,iBAAA,CAHA,iBxBsnFJ,CwB1mFI,oEACE,exB4mFN,CwB7mFI,iEACE,exB4mFN,CwB7mFI,2DACE,exB4mFN,CwBxmFI,2DAME,wBCwIU,CDpIV,UAAA,CALA,WAAA,CAEA,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CARA,iBAAA,CACA,UAAA,CAEA,UxBgnFN,CwBpnFI,wDAME,wBCwIU,CDpIV,UAAA,CALA,WAAA,CAEA,0CAAA,CACA,qBAAA,CACA,iBAAA,CARA,iBAAA,CACA,UAAA,CAEA,UxBgnFN,CwBpnFI,qEAGE,UxBinFN,CwBpnFI,kEAGE,UxBinFN,CwBpnFI,4DAGE,UxBinFN,CwBpnFI,qEAGE,WxBinFN,CwBpnFI,kEAGE,WxBinFN,CwBpnFI,4DAGE,WxBinFN,CwBpnFI,kDAME,wBCwIU,CDpIV,UAAA,CALA,WAAA,CAEA,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CARA,iBAAA,CACA,UAAA,CAEA,UxBgnFN,CwBtlFE,iEACE,oBxBylFJ,CwB1lFE,2DACE,oBxBylFJ,CwB1lFE,+CACE,oBxBylFJ,CwBrlFE,wEACE,oCxBwlFJ,CwBzlFE,kEACE,oCxBwlFJ,CwBzlFE,sDACE,oCxBwlFJ,CwBrlFI,+EACE,wBAnBG,CAoBH,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBulFN,CwB3lFI,yEACE,wBAnBG,CAoBH,0CAAA,CACA,qBAAA,CACA,iBxBulFN,CwB3lFI,6DACE,wBAnBG,CAoBH,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBulFN,CwBpmFE,oFACE,oBxBumFJ,CwBxmFE,8EACE,oBxBumFJ,CwBxmFE,kEACE,oBxBumFJ,CwBnmFE,2FACE,mCxBsmFJ,CwBvmFE,qFACE,mCxBsmFJ,CwBvmFE,yEACE,mCxBsmFJ,CwBnmFI,kGACE,wBAnBG,CAoBH,sDAAA,CAAA,8CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBqmFN,CwBzmFI,4FACE,wBAnBG,CAoBH,8CAAA,CACA,qBAAA,CACA,iBxBqmFN,CwBzmFI,gFACE,wBAnBG,CAoBH,sDAAA,CAAA,8CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBqmFN,CwBlnFE,uEACE,oBxBqnFJ,CwBtnFE,iEACE,oBxBqnFJ,CwBtnFE,qDACE,oBxBqnFJ,CwBjnFE,8EACE,mCxBonFJ,CwBrnFE,wEACE,mCxBonFJ,CwBrnFE,4DACE,mCxBonFJ,CwBjnFI,qFACE,wBAnBG,CAoBH,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBmnFN,CwBvnFI,+EACE,wBAnBG,CAoBH,0CAAA,CACA,qBAAA,CACA,iBxBmnFN,CwBvnFI,mEACE,wBAnBG,CAoBH,kDAAA,CAAA,0CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBmnFN,CwBhoFE,iFACE,oBxBmoFJ,CwBpoFE,2EACE,oBxBmoFJ,CwBpoFE,+DACE,oBxBmoFJ,CwB/nFE,wFACE,mCxBkoFJ,CwBnoFE,kFACE,mCxBkoFJ,CwBnoFE,sEACE,mCxBkoFJ,CwB/nFI,+FACE,wBAnBG,CAoBH,iDAAA,CAAA,yCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBioFN,CwBroFI,yFACE,wBAnBG,CAoBH,yCAAA,CACA,qBAAA,CACA,iBxBioFN,CwBroFI,6EACE,wBAnBG,CAoBH,iDAAA,CAAA,yCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBioFN,CwB9oFE,iFACE,oBxBipFJ,CwBlpFE,2EACE,oBxBipFJ,CwBlpFE,+DACE,oBxBipFJ,CwB7oFE,wFACE,kCxBgpFJ,CwBjpFE,kFACE,kCxBgpFJ,CwBjpFE,sEACE,kCxBgpFJ,CwB7oFI,+FACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB+oFN,CwBnpFI,yFACE,wBAnBG,CAoBH,6CAAA,CACA,qBAAA,CACA,iBxB+oFN,CwBnpFI,6EACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB+oFN,CwB5pFE,gFACE,oBxB+pFJ,CwBhqFE,0EACE,oBxB+pFJ,CwBhqFE,8DACE,oBxB+pFJ,CwB3pFE,uFACE,oCxB8pFJ,CwB/pFE,iFACE,oCxB8pFJ,CwB/pFE,qEACE,oCxB8pFJ,CwB3pFI,8FACE,wBAnBG,CAoBH,sDAAA,CAAA,8CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB6pFN,CwBjqFI,wFACE,wBAnBG,CAoBH,8CAAA,CACA,qBAAA,CACA,iBxB6pFN,CwBjqFI,4EACE,wBAnBG,CAoBH,sDAAA,CAAA,8CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB6pFN,CwB1qFE,wFACE,oBxB6qFJ,CwB9qFE,kFACE,oBxB6qFJ,CwB9qFE,sEACE,oBxB6qFJ,CwBzqFE,+FACE,mCxB4qFJ,CwB7qFE,yFACE,mCxB4qFJ,CwB7qFE,6EACE,mCxB4qFJ,CwBzqFI,sGACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB2qFN,CwB/qFI,gGACE,wBAnBG,CAoBH,6CAAA,CACA,qBAAA,CACA,iBxB2qFN,CwB/qFI,oFACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxB2qFN,CwBxrFE,mFACE,oBxB2rFJ,CwB5rFE,6EACE,oBxB2rFJ,CwB5rFE,iEACE,oBxB2rFJ,CwBvrFE,0FACE,mCxB0rFJ,CwB3rFE,oFACE,mCxB0rFJ,CwB3rFE,wEACE,mCxB0rFJ,CwBvrFI,iGACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxByrFN,CwB7rFI,2FACE,wBAnBG,CAoBH,6CAAA,CACA,qBAAA,CACA,iBxByrFN,CwB7rFI,+EACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxByrFN,CwBtsFE,0EACE,oBxBysFJ,CwB1sFE,oEACE,oBxBysFJ,CwB1sFE,wDACE,oBxBysFJ,CwBrsFE,iFACE,mCxBwsFJ,CwBzsFE,2EACE,mCxBwsFJ,CwBzsFE,+DACE,mCxBwsFJ,CwBrsFI,wFACE,wBAnBG,CAoBH,oDAAA,CAAA,4CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBusFN,CwB3sFI,kFACE,wBAnBG,CAoBH,4CAAA,CACA,qBAAA,CACA,iBxBusFN,CwB3sFI,sEACE,wBAnBG,CAoBH,oDAAA,CAAA,4CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBusFN,CwBptFE,gEACE,oBxButFJ,CwBxtFE,0DACE,oBxButFJ,CwBxtFE,8CACE,oBxButFJ,CwBntFE,uEACE,kCxBstFJ,CwBvtFE,iEACE,kCxBstFJ,CwBvtFE,qDACE,kCxBstFJ,CwBntFI,8EACE,wBAnBG,CAoBH,iDAAA,CAAA,yCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBqtFN,CwBztFI,wEACE,wBAnBG,CAoBH,yCAAA,CACA,qBAAA,CACA,iBxBqtFN,CwBztFI,4DACE,wBAnBG,CAoBH,iDAAA,CAAA,yCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBqtFN,CwBluFE,oEACE,oBxBquFJ,CwBtuFE,8DACE,oBxBquFJ,CwBtuFE,kDACE,oBxBquFJ,CwBjuFE,2EACE,oCxBouFJ,CwBruFE,qEACE,oCxBouFJ,CwBruFE,yDACE,oCxBouFJ,CwBjuFI,kFACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBmuFN,CwBvuFI,4EACE,wBAnBG,CAoBH,6CAAA,CACA,qBAAA,CACA,iBxBmuFN,CwBvuFI,gEACE,wBAnBG,CAoBH,qDAAA,CAAA,6CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBmuFN,CwBhvFE,wEACE,oBxBmvFJ,CwBpvFE,kEACE,oBxBmvFJ,CwBpvFE,sDACE,oBxBmvFJ,CwB/uFE,+EACE,kCxBkvFJ,CwBnvFE,yEACE,kCxBkvFJ,CwBnvFE,6DACE,kCxBkvFJ,CwB/uFI,sFACE,wBAnBG,CAoBH,mDAAA,CAAA,2CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBivFN,CwBrvFI,gFACE,wBAnBG,CAoBH,2CAAA,CACA,qBAAA,CACA,iBxBivFN,CwBrvFI,oEACE,wBAnBG,CAoBH,mDAAA,CAAA,2CAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBxBivFN,C0Bv4FA,MACE,wM1B04FF,C0Bj4FE,sBACE,uCAAA,CACA,gB1Bo4FJ,C0Bj4FI,mCACE,a1Bm4FN,C0Bp4FI,mCACE,c1Bm4FN,C0B/3FM,4BACE,sB1Bi4FR,C0B93FQ,mCACE,gC1Bg4FV,C0B53FQ,2DAEE,SAAA,CADA,uBAAA,CAEA,e1B83FV,C0B13FQ,0EAEE,SAAA,CADA,uB1B63FV,C0B93FQ,uEAEE,SAAA,CADA,uB1B63FV,C0B93FQ,iEAEE,SAAA,CADA,uB1B63FV,C0Bx3FQ,yCACE,Y1B03FV,C0Bn3FE,0BAEE,eAAA,CADA,e1Bs3FJ,C0Bl3FI,+BACE,oB1Bo3FN,C0B/2FE,gDACE,Y1Bi3FJ,C0B72FE,8BAEE,+BAAA,CADA,oBAAA,CAGA,WAAA,CAGA,SAAA,CADA,4BAAA,CAEA,4DACE,CAJF,0B1Bi3FJ,C0Bx2FI,aAdF,8BAeI,+BAAA,CAEA,SAAA,CADA,uB1B42FJ,CACF,C0Bx2FI,wCACE,6B1B02FN,C0Bt2FI,oCACE,+B1Bw2FN,C0Bp2FI,qCAIE,6BAAA,CAIA,UAAA,CAPA,oBAAA,CAEA,YAAA,CAEA,2CAAA,CAAA,mCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CALA,W1B42FN,C0Bh2FQ,mDACE,oB1Bk2FV,C2B/8FE,kCAEE,iB3Bq9FJ,C2Bv9FE,kCAEE,kB3Bq9FJ,C2Bv9FE,wBAGE,yCAAA,CAFA,oBAAA,CAGA,SAAA,CACA,mC3Bk9FJ,C2B78FI,aAVF,wBAWI,Y3Bg9FJ,CACF,C2B58FE,mFAEE,SAAA,CACA,2CACE,CADF,mC3B88FJ,C2Bj9FE,gFAEE,SAAA,CACA,wCACE,CADF,mC3B88FJ,C2Bj9FE,0EAEE,SAAA,CACA,mC3B88FJ,C2Bx8FE,mFAEE,+B3B08FJ,C2B58FE,gFAEE,+B3B08FJ,C2B58FE,0EAEE,+B3B08FJ,C2Bt8FE,oBACE,yBAAA,CACA,uBAAA,CAGA,yE3Bs8FJ,CKv0FI,sCsBrHE,qDACE,uB3B+7FN,CACF,C2B17FE,0CACE,yB3B47FJ,C2B77FE,uCACE,yB3B47FJ,C2B77FE,iCACE,yB3B47FJ,C2Bx7FE,sBACE,0B3B07FJ,C4Br/FE,2BACE,a5Bw/FJ,CKn0FI,wCuBtLF,2BAKI,e5Bw/FJ,CACF,C4Br/FI,6BAEE,0BAAA,CAAA,2BAAA,CACA,eAAA,CACA,iBAAA,CAHA,yBAAA,CAAA,sBAAA,CAAA,iB5B0/FN,C4Bp/FM,2CACE,kB5Bs/FR,C6BvgGE,kDACE,kCAAA,CAAA,0B7B0gGJ,C6B3gGE,+CACE,0B7B0gGJ,C6B3gGE,yCACE,kCAAA,CAAA,0B7B0gGJ,C6BtgGE,uBACE,4C7BwgGJ,C6BpgGE,uBACE,4C7BsgGJ,C6BlgGE,4BACE,qC7BogGJ,C6BjgGI,mCACE,a7BmgGN,C6B//FI,kCACE,a7BigGN,C6B5/FE,0BAKE,eAAA,CAJA,aAAA,CACA,YAAA,CAEA,aAAA,CADA,kBAAA,CAAA,mB7BggGJ,C6B3/FI,uCACE,e7B6/FN,C6Bz/FI,sCACE,kB7B2/FN,C8B1iGA,MACE,8L9B6iGF,C8BpiGE,oBACE,iBAAA,CAEA,gBAAA,CADA,a9BwiGJ,C8BpiGI,wCACE,uB9BsiGN,C8BliGI,gCAEE,eAAA,CADA,gB9BqiGN,C8B9hGM,wCACE,mB9BgiGR,C8B1hGE,8BAGE,oB9B+hGJ,C8BliGE,8BAGE,mB9B+hGJ,C8BliGE,8BAIE,4B9B8hGJ,C8BliGE,4DAKE,6B9B6hGJ,C8BliGE,8BAKE,4B9B6hGJ,C8BliGE,oBAME,cAAA,CALA,aAAA,CACA,e9BgiGJ,C8BzhGI,kCACE,uCAAA,CACA,oB9B2hGN,C8BvhGI,wCAEE,uCAAA,CADA,Y9B0hGN,C8BrhGI,oCAGE,W9BgiGN,C8BniGI,oCAGE,U9BgiGN,C8BniGI,0BAME,6BAAA,CAMA,UAAA,CAPA,WAAA,CAEA,yCAAA,CAAA,iCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CARA,iBAAA,CACA,UAAA,CAQA,sBAAA,CACA,yBAAA,CAPA,U9B+hGN,C8BphGM,oCACE,wB9BshGR,C8BjhGI,4BACE,Y9BmhGN,C8B9gGI,4CACE,Y9BghGN,C+BlmGE,qDACE,mBAAA,CACA,cAAA,CACA,uB/BqmGJ,C+BxmGE,kDACE,mBAAA,CACA,cAAA,CACA,uB/BqmGJ,C+BxmGE,4CACE,mBAAA,CACA,cAAA,CACA,uB/BqmGJ,C+BlmGI,yDAGE,iBAAA,CADA,eAAA,CADA,a/BsmGN,C+BvmGI,sDAGE,iBAAA,CADA,eAAA,CADA,a/BsmGN,C+BvmGI,gDAGE,iBAAA,CADA,eAAA,CADA,a/BsmGN,CgC5mGE,gCACE,sChC+mGJ,CgChnGE,6BACE,sChC+mGJ,CgChnGE,uBACE,sChC+mGJ,CgC5mGE,cACE,yChC8mGJ,CgClmGE,4DACE,oChComGJ,CgCrmGE,yDACE,oChComGJ,CgCrmGE,mDACE,oChComGJ,CgC5lGE,6CACE,qChC8lGJ,CgC/lGE,0CACE,qChC8lGJ,CgC/lGE,oCACE,qChC8lGJ,CgCplGE,oDACE,oChCslGJ,CgCvlGE,iDACE,oChCslGJ,CgCvlGE,2CACE,oChCslGJ,CgC7kGE,gDACE,qChC+kGJ,CgChlGE,6CACE,qChC+kGJ,CgChlGE,uCACE,qChC+kGJ,CgC1kGE,gCACE,kChC4kGJ,CgC7kGE,6BACE,kChC4kGJ,CgC7kGE,uBACE,kChC4kGJ,CgCtkGE,qCACE,sChCwkGJ,CgCzkGE,kCACE,sChCwkGJ,CgCzkGE,4BACE,sChCwkGJ,CgCjkGE,yCACE,sChCmkGJ,CgCpkGE,sCACE,sChCmkGJ,CgCpkGE,gCACE,sChCmkGJ,CgC5jGE,yCACE,qChC8jGJ,CgC/jGE,sCACE,qChC8jGJ,CgC/jGE,gCACE,qChC8jGJ,CgCrjGE,gDACE,qChCujGJ,CgCxjGE,6CACE,qChCujGJ,CgCxjGE,uCACE,qChCujGJ,CgC/iGE,6CACE,sChCijGJ,CgCljGE,0CACE,sChCijGJ,CgCljGE,oCACE,sChCijGJ,CgCtiGE,yDACE,qChCwiGJ,CgCziGE,sDACE,qChCwiGJ,CgCziGE,gDACE,qChCwiGJ,CgCniGE,iCAGE,mBAAA,CAFA,gBAAA,CACA,gBhCsiGJ,CgCxiGE,8BAGE,mBAAA,CAFA,gBAAA,CACA,gBhCsiGJ,CgCxiGE,wBAGE,mBAAA,CAFA,gBAAA,CACA,gBhCsiGJ,CgCliGE,eACE,4ChCoiGJ,CgCjiGE,eACE,4ChCmiGJ,CgC/hGE,gBAIE,wCAAA,CAHA,aAAA,CACA,wBAAA,CACA,wBhCkiGJ,CgC7hGE,yBAOE,wCAAA,CACA,+DAAA,CACA,4BAAA,CACA,6BAAA,CARA,iBAAA,CAIA,eAAA,CADA,eAAA,CAFA,cAAA,CACA,oCAAA,CAHA,iBhCwiGJ,CgC5hGI,6BACE,YhC8hGN,CgC3h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jC8+GV,CiC/+GQ,+CACE,QjCi/GV,CiCl/GQ,+CACE,QjCo/GV,CiCr/GQ,+CACE,QjCu/GV,CiCx/GQ,+CACE,QjC0/GV,CACF,CiCr/GM,uCACE,+BjCu/GR,CiCj/GE,4BACE,UjCm/GJ,CiCh/GI,aAJF,4BAKI,gBjCm/GJ,CACF,CiC/+GE,0BACE,YjCi/GJ,CiC9+GI,aAJF,0BAKI,ajCi/GJ,CiC7+GM,sCACE,OjC++GR,CiCh/GM,uCACE,OjCk/GR,CiCn/GM,uCACE,OjCq/GR,CiCt/GM,uCACE,OjCw/GR,CiCz/GM,uCACE,OjC2/GR,CiC5/GM,uCACE,OjC8/GR,CiC//GM,uCACE,OjCigHR,CiClgHM,uCACE,OjCogHR,CiCrgHM,uCACE,OjCugHR,CiCxgHM,wCACE,QjC0gHR,CiC3gHM,wCACE,QjC6gHR,CiC9gHM,wCACE,QjCghHR,CiCjhHM,wCACE,QjCmhHR,CiCphHM,wCACE,QjCshHR,CiCvhHM,wCACE,QjCyhHR,CiC1hHM,wCACE,QjC4hHR,CiC7hHM,wCACE,QjC+hHR,CiChiHM,wCACE,QjCkiHR,CiCniHM,wCACE,QjCqiHR,CiCtiHM,wCACE,QjCwiHR,CACF,CiCliHI,iKAGE,QjCoiHN,CiCjiHM,8MACE,wBjCsiHR,CiCviHM,4ZAEE,yBjCqiHR,CiChiHI,uRACE,wBjCmiHN,CiCpiHI,kJAEE,yBjCkiHN,CiCpiHI,yEAEE,wBjCkiHN,CiC9hHI,sCACE,QjCgiHN,CK5hHI,wC4BSF,wDAGE,kBjCwhHF,CiC3hHA,wDAGE,mBjCwhHF,CiC3hHA,8CAEE,eAAA,CADA,eAAA,CAGA,iCjCuhHF,CiCnhHE,8DACE,mBjCshHJ,CiCvhHE,8DACE,kBjCshHJ,CiCvhHE,oDAEE,UjCqhHJ,CACF,CiCzgHE,cAHF,olDAII,+BjC4gHF,CiCzgHE,g8GACE,sCjC2gHJ,CACF,CiCtgHA,4sDACE,uDjCygHF,CiCrgHA,wmDACE,ajCwgHF,CkClvHA,MACE,mVAAA,CAEA,4VlCsvHF,CkC5uHE,4BAEE,oBAAA,CADA,iBlCgvHJ,CkC3uHI,sDAGE,SlC6uHN,CkChvHI,sDAGE,UlC6uHN,CkChvHI,4CACE,iBAAA,CACA,SlC8uHN,CkCxuHE,+CAEE,SAAA,CADA,UlC2uHJ,CkCtuHE,kDAGE,WlC+uHJ,CkClvHE,kDAGE,YlC+uHJ,CkClvHE,wCAME,qDAAA,CAIA,UAAA,CALA,aAAA,CAEA,0CAAA,CAAA,kCAAA,CACA,6BAAA,CAAA,qBAAA,CACA,yBAAA,CAAA,iBAAA,CARA,iBAAA,CACA,SAAA,CAEA,YlC8uHJ,CkCpuHE,gEACE,wBT0Wa,CSzWb,mDAAA,CAAA,2ClCsuHJ,CmCvxHA,QACE,8DAAA,CAGA,+CAAA,CACA,iEAAA,CACA,oDAAA,CACA,sDAAA,CACA,mDnCwxHF,CmCpxHA,SAEE,kBAAA,CADA,YnCwxHF,CK/nHI,mC+BhKA,8BAIE,kBpCoyHJ,CoCxyHE,8BAIE,iBpCoyHJ,CoCxyHE,oBACE,UAAA,CAIA,mBAAA,CAFA,YAAA,CADA,apCsyHJ,CoChyHI,8BACE,WpCkyHN,CoC9xHI,kCAEE,iBAAA,CAAA,cpCgyHN,CoClyHI,kCAEE,aAAA,CAAA,kBpCgyHN,CoClyHI,wBACE,WpCiyHN,CoC7xHM,kCACE,UpC+xHR,CACF","file":"main.css"} \ No newline at end of file diff --git a/assets/stylesheets/palette.9647289d.min.css b/assets/stylesheets/palette.cc9b2e1e.min.css similarity index 96% rename from assets/stylesheets/palette.9647289d.min.css rename to assets/stylesheets/palette.cc9b2e1e.min.css index ccf1b5aa5..d0fd19a25 100644 --- a/assets/stylesheets/palette.9647289d.min.css +++ b/assets/stylesheets/palette.cc9b2e1e.min.css @@ -1 +1 @@ -[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:rgba(255,25,71,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:rgba(245,0,86,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:rgba(223,65,251,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:rgba(124,77,255,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:rgba(66,135,255,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:rgba(0,145,235,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:rgba(0,186,214,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:rgba(0,189,164,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:rgba(0,199,83,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:rgba(99,222,23,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:rgba(176,235,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:rgba(255,213,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:rgba(255,170,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:rgba(255,145,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:rgba(255,110,66,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=indigo]{--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:hsla(0,0%,100%,.7)}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=white]{--md-primary-fg-color:#fff;--md-primary-fg-color--light:hsla(0,0%,100%,.7);--md-primary-fg-color--dark:rgba(0,0,0,.07);--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54);--md-typeset-a-color:#4051b5}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:rgba(0,0,0,.07)}[data-md-color-primary=white] .md-search__form:hover{background-color:rgba(0,0,0,.32)}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:rgba(0,0,0,.87)}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid rgba(0,0,0,.07)}}[data-md-color-primary=black]{--md-primary-fg-color:#000;--md-primary-fg-color--light:rgba(0,0,0,.54);--md-primary-fg-color--dark:#000;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-header{background-color:#000}@media screen and (max-width:59.9375em){[data-md-color-primary=black] .md-nav__source{background-color:rgba(0,0,0,.87)}}@media screen and (min-width:60em){[data-md-color-primary=black] .md-search__form{background-color:hsla(0,0%,100%,.12)}[data-md-color-primary=black] .md-search__form:hover{background-color:hsla(0,0%,100%,.3)}}@media screen and (max-width:76.1875em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:#000}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:#000}}@media screen{[data-md-color-scheme=slate]{--md-hue:232;--md-default-fg-color:hsla(var(--md-hue),75%,95%,1);--md-default-fg-color--light:hsla(var(--md-hue),75%,90%,0.62);--md-default-fg-color--lighter:hsla(var(--md-hue),75%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),75%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,21%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,21%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,21%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,21%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,1);--md-code-bg-color:hsla(var(--md-hue),15%,15%,1);--md-code-hl-color:rgba(66,135,255,.15);--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--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-mark-color:rgba(66,135,255,.3);--md-typeset-kbd-color:hsla(var(--md-hue),15%,94%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,94%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-table-color:hsla(var(--md-hue),75%,95%,0.12);--md-admonition-bg-color:hsla(var(--md-hue),0%,100%,0.025);--md-footer-bg-color:hsla(var(--md-hue),15%,12%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,10%,1)}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#5d6cc0}[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate] img[src$="#only-dark"]{display:initial}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}} \ No newline at end of file +[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:rgba(255,25,71,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:rgba(245,0,86,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:rgba(223,65,251,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:rgba(124,77,255,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:rgba(82,108,254,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:rgba(66,135,255,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:rgba(0,145,235,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:rgba(0,186,214,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:rgba(0,189,164,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:rgba(0,199,83,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:rgba(99,222,23,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:rgba(176,235,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:rgba(255,213,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:rgba(255,170,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:rgba(255,145,0,.1);--md-accent-bg-color:rgba(0,0,0,.87);--md-accent-bg-color--light:rgba(0,0,0,.54)}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:rgba(255,110,66,.1);--md-accent-bg-color:#fff;--md-accent-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=indigo]{--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:hsla(0,0%,100%,.7)}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54)}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7)}[data-md-color-primary=white]{--md-primary-fg-color:#fff;--md-primary-fg-color--light:hsla(0,0%,100%,.7);--md-primary-fg-color--dark:rgba(0,0,0,.07);--md-primary-bg-color:rgba(0,0,0,.87);--md-primary-bg-color--light:rgba(0,0,0,.54);--md-typeset-a-color:#4051b5}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:rgba(0,0,0,.07)}[data-md-color-primary=white] .md-search__form:hover{background-color:rgba(0,0,0,.32)}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:rgba(0,0,0,.87)}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid rgba(0,0,0,.07)}}[data-md-color-primary=black]{--md-primary-fg-color:#000;--md-primary-fg-color--light:rgba(0,0,0,.54);--md-primary-fg-color--dark:#000;--md-primary-bg-color:#fff;--md-primary-bg-color--light:hsla(0,0%,100%,.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-header{background-color:#000}@media screen and (max-width:59.9375em){[data-md-color-primary=black] .md-nav__source{background-color:rgba(0,0,0,.87)}}@media screen and (min-width:60em){[data-md-color-primary=black] .md-search__form{background-color:hsla(0,0%,100%,.12)}[data-md-color-primary=black] .md-search__form:hover{background-color:hsla(0,0%,100%,.3)}}@media screen and (max-width:76.1875em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:#000}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:#000}}@media screen{[data-md-color-scheme=slate]{--md-hue:232;--md-default-fg-color:hsla(var(--md-hue),75%,95%,1);--md-default-fg-color--light:hsla(var(--md-hue),75%,90%,0.62);--md-default-fg-color--lighter:hsla(var(--md-hue),75%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),75%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,21%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,21%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,21%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,21%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,1);--md-code-bg-color:hsla(var(--md-hue),15%,15%,1);--md-code-hl-color:rgba(66,135,255,.15);--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--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-mark-color:rgba(66,135,255,.3);--md-typeset-kbd-color:hsla(var(--md-hue),15%,94%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,94%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-table-color:hsla(var(--md-hue),75%,95%,0.12);--md-admonition-bg-color:hsla(var(--md-hue),0%,100%,0.025);--md-footer-bg-color:hsla(var(--md-hue),15%,12%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,10%,1)}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#5d6cc0}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=slate] img[src$="#only-dark"]{display:initial}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}} \ No newline at end of file diff --git a/assets/stylesheets/palette.9647289d.min.css.map b/assets/stylesheets/palette.cc9b2e1e.min.css.map similarity index 96% rename from assets/stylesheets/palette.9647289d.min.css.map rename to assets/stylesheets/palette.cc9b2e1e.min.css.map index 29eeaa4da..46620900a 100644 --- a/assets/stylesheets/palette.9647289d.min.css.map +++ b/assets/stylesheets/palette.cc9b2e1e.min.css.map @@ -1 +1 @@ -{"version":3,"sources":["src/assets/stylesheets/palette/_accent.scss","../../../src/assets/stylesheets/palette.scss","src/assets/stylesheets/palette/_primary.scss","src/assets/stylesheets/utilities/_break.scss","src/assets/stylesheets/palette/_scheme.scss"],"names":[],"mappings":"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","file":"palette.css"} \ No newline at end of file +{"version":3,"sources":["src/assets/stylesheets/palette/_accent.scss","../../../src/assets/stylesheets/palette.scss","src/assets/stylesheets/palette/_primary.scss","src/assets/stylesheets/utilities/_break.scss","src/assets/stylesheets/palette/_scheme.scss"],"names":[],"mappings":"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","file":"palette.css"} \ No newline at end of file diff --git a/backup_restore/b_n_r-accidental_deletion/index.html b/backup_restore/b_n_r-accidental_deletion/index.html index 84cecceee..5518dd087 100644 --- a/backup_restore/b_n_r-accidental_deletion/index.html +++ b/backup_restore/b_n_r-accidental_deletion/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2456,9 +2456,8 @@

    To restore make sure you are actually restoring to the same mailcow it was deleted from or you use the same encryption keys in crypt-vol-1.

    Make sure the user you want to restore exists in your mailcow. Re-create them if they are missing.

    Copy the folders from /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/_garbage/[timestamp]_[domain_sanitized][user_sanitized] back to /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/[domain]/[user] and resync the folder and recalc the quota:

    -
    docker-compose exec dovecot-mailcow doveadm force-resync -u restoreme@example.net '*'
    -docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.net
    -
    +

    docker-compose exec dovecot-mailcow doveadm force-resync -u restoreme@example.net '*' +docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.net


    @@ -2578,7 +2577,7 @@ docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.ne - + diff --git a/backup_restore/b_n_r-backup/index.html b/backup_restore/b_n_r-backup/index.html index 74ed97093..373e1aa6c 100644 --- a/backup_restore/b_n_r-backup/index.html +++ b/backup_restore/b_n_r-backup/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -961,6 +961,47 @@ + + + + + +
  • + + Syntax: + + +
  • + +
  • + + ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days) + + +
  • + +
  • + + Backup all, delete backups older than 3 days + + +
  • + +
  • + + Backup vmail, crypt and mysql data, delete backups older than 30 days + + +
  • + +
  • + + Backup vmail + + + +
  • + +
  • + + !/bin/sh + + +
  • + +
  • + + Backup mailcow data + + +
  • + +
  • + + https://mailcow.github.io/mailcow-dockerized-docs/backup_restore/b_n_r-backup/ + + +
  • + +
  • + + run command + +
  • @@ -978,6 +1047,13 @@ Backup strategy with rsync and mailcow backup script +
  • + +
  • + + If you want to, use the acl util to backup permissions of some/all folders/files: getfacl -Rn /path + +
  • @@ -2439,6 +2515,47 @@ + + + + + +
  • + + Syntax: + + +
  • + +
  • + + ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days) + + +
  • + +
  • + + Backup all, delete backups older than 3 days + + +
  • + +
  • + + Backup vmail, crypt and mysql data, delete backups older than 30 days + + +
  • + +
  • + + Backup vmail + + + +
  • + +
  • + + !/bin/sh + + +
  • + +
  • + + Backup mailcow data + + +
  • + +
  • + + https://mailcow.github.io/mailcow-dockerized-docs/backup_restore/b_n_r-backup/ + + +
  • + +
  • + + run command + +
  • @@ -2456,6 +2601,13 @@ Backup strategy with rsync and mailcow backup script +
  • + +
  • + + If you want to, use the acl util to backup permissions of some/all folders/files: getfacl -Rn /path + +
  • @@ -2482,65 +2634,57 @@

    Please do not copy this script to another location.

    To run a backup, write "backup" as first parameter and either one or more components to backup as following parameters. You can also use "all" as second parameter to backup all components. Append --delete-days n to delete backups older than n days.

    -
    # Syntax:
    -# ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days)
    -
    -# Backup all, delete backups older than 3 days
    -./helper-scripts/backup_and_restore.sh backup all --delete-days 3
    -
    -# Backup vmail, crypt and mysql data, delete backups older than 30 days
    -./helper-scripts/backup_and_restore.sh backup vmail crypt mysql --delete-days 30
    -
    -# Backup vmail
    -./helper-scripts/backup_and_restore.sh backup vmail
    -
    +

    ```

    +

    Syntax:

    +

    ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days)

    +

    Backup all, delete backups older than 3 days

    +

    ./helper-scripts/backup_and_restore.sh backup all --delete-days 3

    +

    Backup vmail, crypt and mysql data, delete backups older than 30 days

    +

    ./helper-scripts/backup_and_restore.sh backup vmail crypt mysql --delete-days 30

    +

    Backup vmail

    +

    ./helper-scripts/backup_and_restore.sh backup vmail

    +

    ```

    The script will ask you for a backup location. Inside of this location it will create folders in the format "mailcow_DATE". You should not rename those folders to not break the restore process.

    To run a backup unattended, define MAILCOW_BACKUP_LOCATION as environment variable before starting the script:

    -
    MAILCOW_BACKUP_LOCATION=/opt/backup /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all
    -
    +

    MAILCOW_BACKUP_LOCATION=/opt/backup /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all

    Cronjob

    You can run the backup script regularly via cronjob. Make sure BACKUP_LOCATION exists:

    -
    5 4 * * * cd /opt/mailcow-dockerized/; MAILCOW_BACKUP_LOCATION=/mnt/mailcow_backups /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3
    -
    +

    5 4 * * * cd /opt/mailcow-dockerized/; MAILCOW_BACKUP_LOCATION=/mnt/mailcow_backups /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3

    Per default cron sends the full result of each backup operation by email. If you want cron to only mail on error (non-zero exit code) you may want to use the following snippet. Pathes need to be modified according to your setup (this script is a user contribution).

    This following script may be placed in /etc/cron.daily/mailcow-backup - do not forget to mark it as executable via chmod +x:

    -
    #!/bin/sh
    -
    -# Backup mailcow data
    -# https://mailcow.github.io/mailcow-dockerized-docs/backup_restore/b_n_r-backup/
    -
    -set -e
    -
    -OUT="$(mktemp)"
    -export MAILCOW_BACKUP_LOCATION="/opt/backup"
    -SCRIPT="/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh"
    -PARAMETERS="backup all"
    -OPTIONS="--delete-days 30"
    -
    -# run command
    -set +e
    -"${SCRIPT}" ${PARAMETERS} ${OPTIONS} 2>&1 > "$OUT"
    -RESULT=$?
    -
    -if [ $RESULT -ne 0 ]
    +

    ```

    +

    !/bin/sh

    +

    Backup mailcow data

    +

    https://mailcow.github.io/mailcow-dockerized-docs/backup_restore/b_n_r-backup/

    +

    set -e

    +

    OUT="$(mktemp)" +export MAILCOW_BACKUP_LOCATION="/opt/backup" +SCRIPT="/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh" +PARAMETERS="backup all" +OPTIONS="--delete-days 30"

    +

    run command

    +

    set +e +"${SCRIPT}" ${PARAMETERS} ${OPTIONS} 2>&1 > "$OUT" +RESULT=$?

    +

    if [ $RESULT -ne 0 ] then - echo "${SCRIPT} ${PARAMETERS} ${OPTIONS} encounters an error:" - echo "RESULT=$RESULT" - echo "STDOUT / STDERR:" - cat "$OUT" + echo "${SCRIPT} ${PARAMETERS} ${OPTIONS} encounters an error:" + echo "RESULT=$RESULT" + echo "STDOUT / STDERR:" + cat "$OUT" fi -

    +```

    Backup strategy with rsync and mailcow backup script

    Create the destination directory for mailcows helper script: -

    mkdir -p /external_share/backups/backup_script
    -

    +mkdir -p /external_share/backups/backup_script

    Create cronjobs: -

    25 1 * * * rsync -aH --delete /opt/mailcow-dockerized /external_share/backups/mailcow-dockerized
    +```
    +25 1 * * * rsync -aH --delete /opt/mailcow-dockerized /external_share/backups/mailcow-dockerized
     40 2 * * * rsync -aH --delete /var/lib/docker/volumes /external_share/backups/var_lib_docker_volumes
    -5 4 * * * cd /opt/mailcow-dockerized/; BACKUP_LOCATION=/external_share/backups/backup_script /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3
    -# If you want to, use the acl util to backup permissions of some/all folders/files: getfacl -Rn /path
    -

    +5 4 * * * cd /opt/mailcow-dockerized/; BACKUP_LOCATION=/external_share/backups/backup_script /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3

    +

    If you want to, use the acl util to backup permissions of some/all folders/files: getfacl -Rn /path

    +

    ```

    On the destination (in this case /external_share/backups) you may want to have snapshot capabilities (ZFS, Btrfs etc.). Snapshot daily and keep for n days for a consistent backup. Do not rsync to a Samba share, you need to keep the correct permissions!

    To restore you'd simply need to run rsync the other way round and restart Docker to re-read the volumes. Run docker-compose pull and docker-compose up -d.

    @@ -2665,7 +2809,7 @@ In case of a corrupted database you'd need to use the helper script to restore t - + diff --git a/backup_restore/b_n_r-backup_restore-maildir/index.html b/backup_restore/b_n_r-backup_restore-maildir/index.html index 6d2cb533a..25c1750c3 100644 --- a/backup_restore/b_n_r-backup_restore-maildir/index.html +++ b/backup_restore/b_n_r-backup_restore-maildir/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2440,15 +2440,13 @@

    Backup

    This line backups the vmail directory to a file backup_vmail.tar.gz in the mailcow root directory: -

    cd /path/to/mailcow-dockerized
    -docker run --rm -i -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar cvfz /backup/backup_vmail.tar.gz /vmail
    -

    +cd /path/to/mailcow-dockerized +docker run --rm -i -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar cvfz /backup/backup_vmail.tar.gz /vmail

    You can change the path by adjusting ${PWD} (which equals to the current directory) to any path you have write-access to. Set the filename backup_vmail.tar.gz to any custom name, but leave the path as it is. Example: [...] tar cvfz /backup/my_own_filename_.tar.gz

    Restore

    -
    cd /path/to/mailcow-dockerized
    -docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar xvfz /backup/backup_vmail.tar.gz
    -
    +

    cd /path/to/mailcow-dockerized +docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar xvfz /backup/backup_vmail.tar.gz


    @@ -2568,7 +2566,7 @@ docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if e - + diff --git a/backup_restore/b_n_r-backup_restore-mysql/index.html b/backup_restore/b_n_r-backup_restore-mysql/index.html index 786336085..318a3a4c6 100644 --- a/backup_restore/b_n_r-backup_restore-mysql/index.html +++ b/backup_restore/b_n_r-backup_restore-mysql/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2439,20 +2439,18 @@

    MySQL (mysqldump)

    Backup

    -
    cd /path/to/mailcow-dockerized
    +

    cd /path/to/mailcow-dockerized source mailcow.conf -DATE=$(date +"%Y%m%d_%H%M%S") -docker-compose exec -T mysql-mailcow mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql -

    +DATE=$(date +"%Y%m%d_%H%M%S") +docker-compose exec -T mysql-mailcow mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql

    Restore

    Warning

    You should redirect the SQL dump without docker-compose to prevent parsing errors.

    -
    cd /path/to/mailcow-dockerized
    +

    cd /path/to/mailcow-dockerized source mailcow.conf -docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < backup_file.sql -

    +docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < backup_file.sql


    @@ -2572,7 +2570,7 @@ docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPAS - + diff --git a/backup_restore/b_n_r-coldstandby/index.html b/backup_restore/b_n_r-coldstandby/index.html index b1062cb75..a13979b0b 100644 --- a/backup_restore/b_n_r-coldstandby/index.html +++ b/backup_restore/b_n_r-coldstandby/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2487,10 +2487,9 @@

    You will need a SSH-enabled destination and a keyfile to connect to said destination. The key should not be protected by a password for the script to work unattended.

    In your mailcow base directory, e.g. /opt/mailcow-dockerized you will find a file create_cold_standby.sh.

    Edit this file and change the exported variables:

    -
    export REMOTE_SSH_KEY=/path/to/keyfile
    +

    export REMOTE_SSH_KEY=/path/to/keyfile export REMOTE_SSH_PORT=22 -export REMOTE_SSH_HOST=mailcow-backup.host.name -

    +export REMOTE_SSH_HOST=mailcow-backup.host.name

    The key must be owned and readable by root only.

    Both the source and destination require rsync >= v3.1.0. The destination must have Docker and docker-compose v1 available.

    @@ -2498,28 +2497,23 @@ The destination must have Docker and docker-compose v1 availabl

    You may want to test the connection by running ssh mailcow-backup.host.name -p22 -i /path/to/keyfile.

    Backup and refresh the cold-standby

    Run the first backup, this may take a while depending on the connection:

    -
    bash /opt/mailcow-dockerized/create_cold_standby.sh
    -
    +

    bash /opt/mailcow-dockerized/create_cold_standby.sh

    That was easy, wasn't it?

    Updating your cold-standby is just as easy:

    -
    bash /opt/mailcow-dockerized/create_cold_standby.sh
    -
    +

    bash /opt/mailcow-dockerized/create_cold_standby.sh

    It's the same command.

    Automated backups with cron

    First make sure that the cron service is enabled and running:

    -
    systemctl enable cron.service && systemctl start cron.service
    -
    +

    systemctl enable cron.service && systemctl start cron.service

    To automate the backups to the cold-standby server you can use a cron job. To edit the cron jobs for the root user run:

    -
    crontab -e
    -
    +

    crontab -e

    Add the following lines to synchronize the cold standby server daily at 03:00. In this example errors of the last execution are logged into a file.

    -
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    -
    -0 3 * * * bash /opt/mailcow-dockerized/create_cold_standby.sh 2> /var/log/mailcow-coldstandby-sync.log
    -
    +

    ``` +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

    +

    0 3 * * * bash /opt/mailcow-dockerized/create_cold_standby.sh 2> /var/log/mailcow-coldstandby-sync.log +```

    If saved correctly, the cron job should be shown by typing:

    -
    crontab -l
    -
    +

    crontab -l


    @@ -2639,7 +2633,7 @@ The destination must have Docker and docker-compose v1 availabl - + diff --git a/backup_restore/b_n_r-restore/index.html b/backup_restore/b_n_r-restore/index.html index c6b561fed..af81d3aeb 100644 --- a/backup_restore/b_n_r-restore/index.html +++ b/backup_restore/b_n_r-restore/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -965,6 +965,20 @@ Restore + + +
  • + + Syntax: + + +
  • + +
  • + + ./helper-scripts/backup_and_restore.sh restore + +
  • @@ -2402,6 +2416,20 @@ Restore + + +
  • + + Syntax: + + +
  • + +
  • + + ./helper-scripts/backup_and_restore.sh restore + +
  • @@ -2422,14 +2450,13 @@ -

    Restore

    -

    Restore

    Please do not copy this script to another location.

    To run a restore, start mailcow, use the script with "restore" as first parameter.

    -
    # Syntax:
    -# ./helper-scripts/backup_and_restore.sh restore
    -
    +

    ```

    +

    Syntax:

    +

    ./helper-scripts/backup_and_restore.sh restore

    +

    ```

    The script will ask you for a backup location containing the mailcow_DATE folders.


    @@ -2550,7 +2577,7 @@ - + diff --git a/client/client-android/index.html b/client/client-android/index.html index dd2e3d6cc..7d1546eb2 100644 --- a/client/client-android/index.html +++ b/client/client-android/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2499,7 +2499,7 @@ - + diff --git a/client/client-apple/index.html b/client/client-apple/index.html index 13d95ab43..ecde48943 100644 --- a/client/client-apple/index.html +++ b/client/client-apple/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2607,7 +2607,7 @@ - + diff --git a/client/client-emclient/index.html b/client/client-emclient/index.html index 2af1d095b..1ef680a44 100644 --- a/client/client-emclient/index.html +++ b/client/client-emclient/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2501,7 +2501,7 @@ - + diff --git a/client/client-kontact/index.html b/client/client-kontact/index.html index eae5704e3..80d806456 100644 --- a/client/client-kontact/index.html +++ b/client/client-kontact/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2509,7 +2509,7 @@ - + diff --git a/client/client-manual/index.html b/client/client-manual/index.html index 922277bf2..da85ed2da 100644 --- a/client/client-manual/index.html +++ b/client/client-manual/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2613,7 +2613,7 @@ - + diff --git a/client/client-outlook/index.html b/client/client-outlook/index.html index 8b1344e84..a40e71141 100644 --- a/client/client-outlook/index.html +++ b/client/client-outlook/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2639,7 +2639,7 @@ - + diff --git a/client/client-thunderbird/index.html b/client/client-thunderbird/index.html index 87ee2bc2f..86b0b6ad5 100644 --- a/client/client-thunderbird/index.html +++ b/client/client-thunderbird/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2518,7 +2518,7 @@ - + diff --git a/client/client-windows/index.html b/client/client-windows/index.html index 6edc8a1b2..3c9a5baea 100644 --- a/client/client-windows/index.html +++ b/client/client-windows/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2502,7 +2502,7 @@ - + diff --git a/client/client/index.html b/client/client/index.html index d2b90d0da..6eb3febeb 100644 --- a/client/client/index.html +++ b/client/client/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2516,7 +2516,7 @@ Since you accessed this page after logging into your mailcow server, all of the - + diff --git a/de/backup_restore/b_n_r-accidental_deletion/index.html b/de/backup_restore/b_n_r-accidental_deletion/index.html index 2354c8d68..e86cfa3cf 100644 --- a/de/backup_restore/b_n_r-accidental_deletion/index.html +++ b/de/backup_restore/b_n_r-accidental_deletion/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2456,9 +2456,8 @@

    Um die Mailbox wiederherzustellen, stellen Sie sicher, dass Sie tatsächlich auf die gleiche Mailcow wiederherstellen, von der sie gelöscht wurde, oder Sie verwenden die gleichen Verschlüsselungsschlüssel in crypt-vol-1.

    Stellen Sie sicher, dass der Benutzer, den Sie wiederherstellen wollen, in Ihrer Mailcow existiert. Legen Sie diesen neu an, wenn der Benutzer fehlt.

    Kopieren Sie die Ordner von /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/_garbage/[timestamp]_[domain_sanitized][user_sanitized] zurück nach /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/[domain]/[user] und synchronisieren Sie die Ordner neu und berechnen Sie die Quota (Speicherplatz) neu:

    -
    docker-compose exec dovecot-mailcow doveadm force-resync -u restoreme@example.net '*'
    -docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.net
    -
    +

    docker-compose exec dovecot-mailcow doveadm force-resync -u restoreme@example.net '*' +docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.net


    @@ -2578,7 +2577,7 @@ docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.ne - + diff --git a/de/backup_restore/b_n_r-backup/index.html b/de/backup_restore/b_n_r-backup/index.html index cd8725180..6f03929bf 100644 --- a/de/backup_restore/b_n_r-backup/index.html +++ b/de/backup_restore/b_n_r-backup/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -961,6 +961,47 @@ + + + + + +
  • + + Syntax: + + +
  • + +
  • + + ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days) + + +
  • + +
  • + + Alles sichern, Sicherungen älter als 3 Tage löschen + + +
  • + +
  • + + vmail-, crypt- und mysql-Daten sichern, Sicherungen löschen, die älter als 30 Tage sind + + +
  • + +
  • + + vmail sichern + + + +
  • + +
  • + + !/bin/sh + + +
  • + +
  • + + Backup mailcow data + + +
  • + +
  • + + https://mailcow.github.io/mailcow-dockerized-docs/b_n_r_backup/ + + +
  • + +
  • + + run command + + +
  • + +
  • + + https://mailcow.github.io/mailcow-dockerized-docs/b_n_r_backup/ + + +
  • + +
  • + + Befehl ausführen + +
  • @@ -978,6 +1061,13 @@ Backup-Strategie mit rsync und mailcow Backup-Skript +
  • + +
  • + + Wenn Sie wollen, benutzen Sie acl util, um die Berechtigungen einiger/aller Ordner/Dateien zu sichern: getfacl -Rn /path + +
  • @@ -2439,6 +2529,47 @@ + + + + + +
  • + + Syntax: + + +
  • + +
  • + + ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days) + + +
  • + +
  • + + Alles sichern, Sicherungen älter als 3 Tage löschen + + +
  • + +
  • + + vmail-, crypt- und mysql-Daten sichern, Sicherungen löschen, die älter als 30 Tage sind + + +
  • + +
  • + + vmail sichern + + + +
  • + +
  • + + !/bin/sh + + +
  • + +
  • + + Backup mailcow data + + +
  • + +
  • + + https://mailcow.github.io/mailcow-dockerized-docs/b_n_r_backup/ + + +
  • + +
  • + + run command + + +
  • + +
  • + + https://mailcow.github.io/mailcow-dockerized-docs/b_n_r_backup/ + + +
  • + +
  • + + Befehl ausführen + +
  • @@ -2456,6 +2629,13 @@ Backup-Strategie mit rsync und mailcow Backup-Skript +
  • + +
  • + + Wenn Sie wollen, benutzen Sie acl util, um die Berechtigungen einiger/aller Ordner/Dateien zu sichern: getfacl -Rn /path + +
  • @@ -2482,84 +2662,72 @@

    Bitte kopieren Sie dieses Skript nicht an einen anderen Ort.

    Um ein Backup zu starten, geben Sie "backup" als ersten Parameter an und entweder eine oder mehrere zu sichernde Komponenten als folgende Parameter. Sie können auch "all" als zweiten Parameter verwenden, um alle Komponenten zu sichern. Fügen Sie --delete-days n an, um Sicherungen zu löschen, die älter als n Tage sind.

    -
    # Syntax:
    -# ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days)
    -
    -# Alles sichern, Sicherungen älter als 3 Tage löschen
    -./helper-scripts/backup_and_restore.sh backup all --delete-days 3
    -
    -# vmail-, crypt- und mysql-Daten sichern, Sicherungen löschen, die älter als 30 Tage sind
    -./helper-scripts/backup_and_restore.sh backup vmail crypt mysql --delete-days 30
    -
    -# vmail sichern
    -./helper-scripts/backup_and_restore.sh backup vmail
    -
    +

    ```

    +

    Syntax:

    +

    ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days)

    +

    Alles sichern, Sicherungen älter als 3 Tage löschen

    +

    ./helper-scripts/backup_and_restore.sh backup all --delete-days 3

    +

    vmail-, crypt- und mysql-Daten sichern, Sicherungen löschen, die älter als 30 Tage sind

    +

    ./helper-scripts/backup_and_restore.sh backup vmail crypt mysql --delete-days 30

    +

    vmail sichern

    +

    ./helper-scripts/backup_and_restore.sh backup vmail

    +

    ```

    Das Skript wird Sie nach einem Speicherort für die Sicherung fragen. Innerhalb dieses Speicherortes wird es Ordner im Format "mailcow_DATE" erstellen. Sie sollten diese Ordner nicht umbenennen, um den Wiederherstellungsprozess nicht zu unterbrechen.

    Um ein Backup unbeaufsichtigt durchzuführen, definieren Sie MAILCOW_BACKUP_LOCATION als Umgebungsvariable bevor Sie das Skript starten:

    -
    MAILCOW_BACKUP_LOCATION=/opt/backup /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all
    -
    +

    MAILCOW_BACKUP_LOCATION=/opt/backup /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all

    Cronjob

    Sie können das Backup-Skript regelmäßig über einen Cronjob laufen lassen. Stellen Sie sicher, dass BACKUP_LOCATION existiert:

    -
    5 4 * * * cd /opt/mailcow-dockerized/; MAILCOW_BACKUP_LOCATION=/mnt/mailcow_backups /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3
    -
    +

    5 4 * * * cd /opt/mailcow-dockerized/; MAILCOW_BACKUP_LOCATION=/mnt/mailcow_backups /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3

    Standardmäßig sendet Cron das komplette Ergebnis jeder Backup-Operation per E-Mail. Wenn Sie möchten, dass cron nur im Fehlerfall (Exit-Code ungleich Null) eine E-Mail sendet, können Sie den folgenden Ausschnitt verwenden. Die Pfade müssen entsprechend Ihrer Einrichtung angepasst werden (dieses Skript ist ein Beitrag des Benutzers).

    Das folgende Skript kann in /etc/cron.daily/mailcow-backup platziert werden - vergessen Sie nicht, es mit chmod +x als ausführbar zu markieren:

    -
    #!/bin/sh
    -
    -# Backup mailcow data
    -# https://mailcow.github.io/mailcow-dockerized-docs/b_n_r_backup/
    -
    -set -e
    -
    -OUT="$(mktemp)"
    -export MAILCOW_BACKUP_LOCATION="/opt/backup"
    -SCRIPT="/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh"
    -PARAMETERS="backup all"
    -OPTIONS="--delete-days 30"
    -
    -# run command
    -set +e
    -"${SCRIPT}" ${PARAMETERS} ${OPTIONS} 2>&1 > "$OUT"
    -RESULT=$?
    -
    -if [ $RESULT -ne 0 ]
    +

    ```

    +

    !/bin/sh

    +

    Backup mailcow data

    +

    https://mailcow.github.io/mailcow-dockerized-docs/b_n_r_backup/

    +

    set -e

    +

    OUT="$(mktemp)" +export MAILCOW_BACKUP_LOCATION="/opt/backup" +SCRIPT="/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh" +PARAMETERS="backup all" +OPTIONS="--delete-days 30"

    +

    run command

    +

    set +e +"${SCRIPT}" ${PARAMETERS} ${OPTIONS} 2>&1 > "$OUT" +RESULT=$?

    +

    if [ $RESULT -ne 0 ] then - echo "${SCRIPT} ${PARAMETERS} ${OPTIONS} encounters an error:" - echo "RESULT=$RESULT" -# https://mailcow.github.io/mailcow-dockerized-docs/b_n_r_backup/ - -set -e - -OUT="$(mktemp)" -export MAILCOW_BACKUP_LOCATION="/opt/backup" -SCRIPT="/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh" -PARAMETERS="alle sichern" -OPTIONS="--delete-days 30" - -# Befehl ausführen -setzen +e -"${SCRIPT}" ${PARAMETERS} ${OPTIONS} 2>&1 > "$OUT" -ERGEBNIS=$? - -if [ $RESULT -ne 0 ] + echo "${SCRIPT} ${PARAMETERS} ${OPTIONS} encounters an error:" + echo "RESULT=$RESULT"

    +

    https://mailcow.github.io/mailcow-dockerized-docs/b_n_r_backup/

    +

    set -e

    +

    OUT="$(mktemp)" +export MAILCOW_BACKUP_LOCATION="/opt/backup" +SCRIPT="/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh" +PARAMETERS="alle sichern" +OPTIONS="--delete-days 30"

    +

    Befehl ausführen

    +

    setzen +e +"${SCRIPT}" ${PARAMETERS} ${OPTIONS} 2>&1 > "$OUT" +ERGEBNIS=$?

    +

    if [ $RESULT -ne 0 ] dann - echo "${SCRIPT} ${PARAMETER} ${OPTIONS} ist auf einen Fehler gestoßen:" - echo "ERGEBNIS=$ERGEBNIS" - echo "STDOUT / STDERR:" - cat "$OUT" + echo "${SCRIPT} ${PARAMETER} ${OPTIONS} ist auf einen Fehler gestoßen:" + echo "ERGEBNIS=$ERGEBNIS" + echo "STDOUT / STDERR:" + cat "$OUT" fi -

    +```

    Backup-Strategie mit rsync und mailcow Backup-Skript

    Erstellen Sie das Zielverzeichnis für mailcows Hilfsskript: -

    mkdir -p /external_share/backups/backup_script
    -

    +mkdir -p /external_share/backups/backup_script

    Cronjobs erstellen: -

    25 1 * * * rsync -aH --delete /opt/mailcow-dockerized /external_share/backups/mailcow-dockerized
    +```
    +25 1 * * * rsync -aH --delete /opt/mailcow-dockerized /external_share/backups/mailcow-dockerized
     40 2 * * * rsync -aH --delete /var/lib/docker/volumes /external_share/backups/var_lib_docker_volumes
    -5 4 * * * cd /opt/mailcow-dockerized/; BACKUP_LOCATION=/external_share/backups/backup_script /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3
    -# Wenn Sie wollen, benutzen Sie acl util, um die Berechtigungen einiger/aller Ordner/Dateien zu sichern: getfacl -Rn /path
    -

    +5 4 * * * cd /opt/mailcow-dockerized/; BACKUP_LOCATION=/external_share/backups/backup_script /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3

    +

    Wenn Sie wollen, benutzen Sie acl util, um die Berechtigungen einiger/aller Ordner/Dateien zu sichern: getfacl -Rn /path

    +

    ```

    Am Zielort (in diesem Fall /external_share/backups) möchten Sie vielleicht Snapshot-Fähigkeiten haben (ZFS, Btrfs usw.). Machen Sie täglich einen Snapshot und bewahren Sie ihn für n Tage auf, um ein konsistentes Backup zu erhalten. Führen Sie kein rsync auf eine Samba-Freigabe durch, Sie müssen die richtigen Berechtigungen einhalten!

    Zum Wiederherstellen müssen Sie rsync einfach in umgekehrter Richtung ausführen und Docker neu starten, um die Volumes erneut zu lesen. Führen Sie docker-compose pull und docker-compose up -d aus.

    @@ -2684,7 +2852,7 @@ Im Falle einer beschädigten Datenbank müssen Sie das Hilfsskript verwenden, um - + diff --git a/de/backup_restore/b_n_r-backup_restore-maildir/index.html b/de/backup_restore/b_n_r-backup_restore-maildir/index.html index 09e928fdc..0074a6e3e 100644 --- a/de/backup_restore/b_n_r-backup_restore-maildir/index.html +++ b/de/backup_restore/b_n_r-backup_restore-maildir/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2440,15 +2440,13 @@

    Sicherung

    Diese Zeile sichert das vmail-Verzeichnis in eine Datei backup_vmail.tar.gz im mailcow-Root-Verzeichnis: -

    cd /pfad/zu/mailcow-dockerized
    -docker run --rm -i -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar cvfz /backup/backup_vmail.tar.gz /vmail
    -

    +cd /pfad/zu/mailcow-dockerized +docker run --rm -i -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar cvfz /backup/backup_vmail.tar.gz /vmail

    Sie können den Pfad ändern, indem Sie ${PWD} (das dem aktuellen Verzeichnis entspricht) an einen beliebigen Pfad anpassen, auf den Sie Schreibzugriff haben. Setzen Sie den Dateinamen backup_vmail.tar.gz auf einen beliebigen Namen, aber lassen Sie den Pfad so wie er ist. Beispiel: [...] tar cvfz /backup/mein_eigener_filename_.tar.gz

    Wiederherstellen

    -
    cd /pfad/zu/mailcow-dockerized
    -docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar xvfz /backup/backup_vmail.tar.gz
    -
    +

    cd /pfad/zu/mailcow-dockerized +docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar xvfz /backup/backup_vmail.tar.gz


    @@ -2568,7 +2566,7 @@ docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if e - + diff --git a/de/backup_restore/b_n_r-backup_restore-mysql/index.html b/de/backup_restore/b_n_r-backup_restore-mysql/index.html index f59f67173..f979b5505 100644 --- a/de/backup_restore/b_n_r-backup_restore-mysql/index.html +++ b/de/backup_restore/b_n_r-backup_restore-mysql/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2439,20 +2439,18 @@

    MySQL (mysqldump)

    Sicherung

    -
    cd /pfad/zu/mailcow-dockerized
    +

    cd /pfad/zu/mailcow-dockerized source mailcow.conf -DATE=$(Datum +"%Y%m%d_%H%M%S") -docker-compose exec -T mysql-mailcow mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql -

    +DATE=$(Datum +"%Y%m%d_%H%M%S") +docker-compose exec -T mysql-mailcow mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql

    Wiederherstellen

    Warning

    Sie sollten den SQL-Dump ohne docker-compose umleiten, um Parsing-Fehler zu vermeiden.

    -
    cd /pfad/zu/mailcow-dockerized
    +

    cd /pfad/zu/mailcow-dockerized source mailcow.conf -docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < backup_file.sql -

    +docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < backup_file.sql


    @@ -2572,7 +2570,7 @@ docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPAS - + diff --git a/de/backup_restore/b_n_r-coldstandby/index.html b/de/backup_restore/b_n_r-coldstandby/index.html index a148aed67..3a9cb80dd 100644 --- a/de/backup_restore/b_n_r-coldstandby/index.html +++ b/de/backup_restore/b_n_r-coldstandby/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2487,10 +2487,9 @@

    Sie benötigen ein SSH-fähiges Ziel und eine Schlüsseldatei, um sich mit diesem Ziel zu verbinden. Der Schlüssel sollte nicht durch ein Passwort geschützt sein, damit das Skript unbeaufsichtigt arbeiten kann.

    In Ihrem mailcow-Basisverzeichnis, z.B. /opt/mailcow-dockerized, finden Sie eine Datei create_cold_standby.sh.

    Bearbeiten Sie diese Datei und ändern Sie die exportierten Variablen:

    -
    export REMOTE_SSH_KEY=/pfad/zur/keyfile
    +

    export REMOTE_SSH_KEY=/pfad/zur/keyfile export REMOTE_SSH_PORT=22 -export REMOTE_SSH_HOST=mailcow-backup.host.name -

    +export REMOTE_SSH_HOST=mailcow-backup.host.name

    Der Schlüssel muss im Besitz von root sein und darf nur von diesem gelesen werden können.

    Sowohl die Quelle als auch das Ziel benötigen rsync >= v3.1.0. Das Ziel muss über Docker und docker-compose v1 verfügen.

    @@ -2498,28 +2497,23 @@ Das Ziel muss über Docker und docker-compose v1 verfügen.

    Sie können die Verbindung testen, indem Sie ssh mailcow-backup.host.name -p22 -i /path/to/keyfile ausführen.

    Backup und Aktualisierung des Cold-Standby

    Starten Sie das erste Backup, dies kann je nach Verbindung eine Weile dauern:

    -
    bash /opt/mailcow-dockerized/create_cold_standby.sh
    -
    +

    bash /opt/mailcow-dockerized/create_cold_standby.sh

    Das war einfach, nicht wahr?

    Das Aktualisieren des Cold-Standby ist genauso einfach:

    -
    bash /opt/mailcow-dockerized/create_cold_standby.sh
    -
    +

    bash /opt/mailcow-dockerized/create_cold_standby.sh

    Es ist derselbe Befehl.

    Automatisierte Backups mit cron

    Stellen Sie zunächst sicher, dass der cron Dienst aktiviert ist und läuft:

    -
    systemctl enable cron.service && systemctl start cron.service
    -
    +

    systemctl enable cron.service && systemctl start cron.service

    Um die Backups auf dem Cold-Standby-Server zu automatisieren, können Sie einen Cron-Job verwenden. Um die Cron-Jobs für den Root-Benutzer zu bearbeiten, führen Sie aus:

    -
    crontab -e
    -
    +

    crontab -e

    Fügen Sie die folgenden Zeilen hinzu, um den Cold-Standby-Server täglich um 03:00 Uhr zu synchronisieren. In diesem Beispiel werden Fehler der letzten Ausführung in einer Datei protokolliert.

    -
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    -
    -0 3 * * * bash /opt/mailcow-dockerized/create_cold_standby.sh 2> /var/log/mailcow-coldstandby-sync.log
    -
    +

    ``` +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

    +

    0 3 * * * bash /opt/mailcow-dockerized/create_cold_standby.sh 2> /var/log/mailcow-coldstandby-sync.log +```

    Wenn korrekt gespeichert, sollte der Cron-Job durch Eingabe angezeigt werden:

    -
    crontab -l
    -
    +

    crontab -l


    @@ -2639,7 +2633,7 @@ Das Ziel muss über Docker und docker-compose v1 verfügen.

    - + diff --git a/de/backup_restore/b_n_r-restore/index.html b/de/backup_restore/b_n_r-restore/index.html index 53665dc9d..7132eed4a 100644 --- a/de/backup_restore/b_n_r-restore/index.html +++ b/de/backup_restore/b_n_r-restore/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -965,6 +965,20 @@ Wiederherstellung + + +
  • + + Syntax: + + +
  • + +
  • + + ./helper-scripts/backup_and_restore.sh restore + +
  • @@ -2402,6 +2416,20 @@ Wiederherstellung + + +
  • + + Syntax: + + +
  • + +
  • + + ./helper-scripts/backup_and_restore.sh restore + +
  • @@ -2422,14 +2450,13 @@ -

    Wiederherstellung

    -

    Wiederherstellung

    Bitte kopieren Sie dieses Skript nicht an einen anderen Ort.

    Um eine Wiederherstellung durchzuführen, starten Sie mailcow, verwenden Sie das Skript mit "restore" als ersten Parameter.

    -
    # Syntax:
    -# ./helper-scripts/backup_and_restore.sh restore
    -
    +

    ```

    +

    Syntax:

    +

    ./helper-scripts/backup_and_restore.sh restore

    +

    ```

    Das Skript wird Sie nach einem Speicherort für die Sicherung der mailcow_DATE-Ordner fragen.


    @@ -2550,7 +2577,7 @@ - + diff --git a/de/client/client-android/index.html b/de/client/client-android/index.html index 5e584d2d5..328043c71 100644 --- a/de/client/client-android/index.html +++ b/de/client/client-android/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2499,7 +2499,7 @@ - + diff --git a/de/client/client-apple/index.html b/de/client/client-apple/index.html index 2a22ab3eb..6d5f3ce3c 100644 --- a/de/client/client-apple/index.html +++ b/de/client/client-apple/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2607,7 +2607,7 @@ - + diff --git a/de/client/client-emclient/index.html b/de/client/client-emclient/index.html index bbdebba4b..9ec927ce2 100644 --- a/de/client/client-emclient/index.html +++ b/de/client/client-emclient/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2501,7 +2501,7 @@ - + diff --git a/de/client/client-kontact/index.html b/de/client/client-kontact/index.html index f76ea9cc3..bb03fcdc8 100644 --- a/de/client/client-kontact/index.html +++ b/de/client/client-kontact/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2509,7 +2509,7 @@ - + diff --git a/de/client/client-manual/index.html b/de/client/client-manual/index.html index 1861dd6f3..4db24bf1c 100644 --- a/de/client/client-manual/index.html +++ b/de/client/client-manual/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2613,7 +2613,7 @@ - + diff --git a/de/client/client-outlook/index.html b/de/client/client-outlook/index.html index 434ee46e6..b4c0a0eca 100644 --- a/de/client/client-outlook/index.html +++ b/de/client/client-outlook/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2622,7 +2622,7 @@ - + diff --git a/de/client/client-thunderbird/index.html b/de/client/client-thunderbird/index.html index 646d78847..1bfb1fc61 100644 --- a/de/client/client-thunderbird/index.html +++ b/de/client/client-thunderbird/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2518,7 +2518,7 @@ - + diff --git a/de/client/client-windows/index.html b/de/client/client-windows/index.html index 7628744d5..f4f8e3365 100644 --- a/de/client/client-windows/index.html +++ b/de/client/client-windows/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2502,7 +2502,7 @@ - + diff --git a/de/client/client/index.html b/de/client/client/index.html index 690972708..08611ed6e 100644 --- a/de/client/client/index.html +++ b/de/client/client/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2516,7 +2516,7 @@ Da Sie diese Seite aufgerufen haben, nachdem Sie sich in Ihren Mailcow-Server ei - + diff --git a/de/i_u_m/i_u_m_deinstall/index.html b/de/i_u_m/i_u_m_deinstall/index.html index 10991fb47..a9a90ad41 100644 --- a/de/i_u_m/i_u_m_deinstall/index.html +++ b/de/i_u_m/i_u_m_deinstall/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2374,8 +2374,7 @@

    Deinstallation

    Um mailcow: dockerized mit all seinen Volumes, Images und Containern zu entfernen, tun Sie dies:

    -
    docker-compose down -v --rmi all --remove-orphans
    -
    +

    docker-compose down -v --rmi all --remove-orphans

    Info

      @@ -2504,7 +2503,7 @@ - + diff --git a/de/i_u_m/i_u_m_install/index.html b/de/i_u_m/i_u_m_install/index.html index 1502a3d1c..91c248c03 100644 --- a/de/i_u_m/i_u_m_install/index.html +++ b/de/i_u_m/i_u_m_install/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,66 +2380,58 @@ -

      Installation

      -

      Sie benötigen Docker (eine Version >= 20.10.2 ist erforderlich) und Docker Compose (eine Version <= 2.0 ist erforderlich).

      1. Erfahren Sie, wie Sie Docker und Docker Compose installieren.

      Schnelle Installation für die meisten Betriebssysteme:

        -
      • -

        Docker -

        curl -sSL https://get.docker.com/ | CHANNEL=stable sh
        -# Nachdem der Installationsprozess abgeschlossen ist, müssen Sie eventuell den Dienst aktivieren und sicherstellen, dass er gestartet ist (z. B. CentOS 7)
        -systemctl enable --now docker
        -

        -
      • -
      • -

        Docker-Compose

        -
      • +
      • Docker +``` +curl -sSL https://get.docker.com/ | CHANNEL=stable sh
      • +
      +

      Nachdem der Installationsprozess abgeschlossen ist, müssen Sie eventuell den Dienst aktivieren und sicherstellen, dass er gestartet ist (z. B. CentOS 7)

      +

      systemctl enable --now docker +```

      +
        +
      • Docker-Compose

      Warning

      mailcow benötigt die neueste Version von docker-compose v1. Es wird dringend empfohlen, die untenstehenden Befehle zu verwenden, um docker-compose zu installieren. Paket-Manager (z.B. apt, yum) werden wahrscheinlich nicht die richtige Version liefern. Hinweis: Dieser Befehl lädt docker-compose aus dem offiziellen Docker-Github-Repository herunter und ist eine sichere Methode. Das Snippet ermittelt die neueste unterstützte Version von mailcow. In fast allen Fällen ist dies die letzte verfügbare Version (Ausnahmen sind kaputte Versionen oder größere Änderungen, die noch nicht von mailcow unterstützt werden).

      -
      curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose
      -chmod +x /usr/local/bin/docker-compose
      -
      +

      curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose

      Bitte verwenden Sie die neueste verfügbare Docker-Engine und nicht die Engine, die mit Ihrem Distros-Repository ausgeliefert wird.

      1.1.1. Auf SELinux-aktivierten Systemen, z.B. CentOS 7:

      • Prüfen Sie, ob das Paket "container-selinux" auf Ihrem System vorhanden ist:
      -
      rpm -qa | grep container-selinux
      -
      +

      rpm -qa | grep container-selinux

      Wenn der obige Befehl eine leere oder keine Ausgabe liefert, sollten Sie es über Ihren Paketmanager installieren.

      • Prüfen Sie, ob Docker SELinux-Unterstützung aktiviert hat:
      -
      docker info | grep selinux
      -
      +

      docker info | grep selinux

      Wenn der obige Befehl eine leere oder keine Ausgabe liefert, erstellen oder bearbeiten Sie /etc/docker/daemon.json und fügen Sie "selinux-enabled": true hinzu. Beispielhafter Inhalt der Datei:

      -
      {
      -  "selinux-enabled": true
      -}
      -
      +

      { + "selinux-enabled": true +}

      Starten Sie den Docker-Daemon neu und überprüfen Sie, ob SELinux nun aktiviert ist.

      Dieser Schritt ist erforderlich, um sicherzustellen, dass die mailcows-Volumes richtig gekennzeichnet sind, wie in der Compose-Datei angegeben. Wenn Sie daran interessiert sind, wie das funktioniert, können Sie sich die Readme-Datei von https://github.com/containers/container-selinux ansehen, die auf viele nützliche Informationen zu diesem Thema verweist.

      2. Klonen Sie den Master-Zweig des Repositorys und stellen Sie sicher, dass Ihre umask gleich 0022 ist. Bitte klonen Sie das Repository als root-Benutzer und kontrollieren Sie auch den Stack als root. Wir werden die Attribute - wenn nötig - ändern, während wir die Container automatisch bereitstellen und sicherstellen, dass alles gesichert ist. Das update.sh-Skript muss daher ebenfalls als root ausgeführt werden. Es kann notwendig sein, den Besitzer und andere Attribute von Dateien zu ändern, auf die Sie sonst keinen Zugriff haben. Wir geben die Berechtigungen für jede exponierte Anwendung auf und führen einen exponierten Dienst nicht als root aus! Wenn Sie den Docker-Daemon als Nicht-Root-Benutzer steuern, erhalten Sie keine zusätzliche Sicherheit. Der unprivilegierte Benutzer wird die Container ebenfalls als root spawnen. Das Verhalten des Stacks ist identisch.

      -
      $ su
      -# umask
      -0022 # <- Überprüfen, dass es 0022 ist
      -# cd /opt
      -# git clone https://github.com/mailcow/mailcow-dockerized
      -# cd mailcow-dockerized
      -
      +

      ``` +$ su

      +

      umask

      +

      0022 # <- Überprüfen, dass es 0022 ist

      +

      cd /opt

      +

      git clone https://github.com/mailcow/mailcow-dockerized

      +

      cd mailcow-dockerized

      +

      ```

      3. Erzeugen Sie eine Konfigurationsdatei. Verwenden Sie einen FQDN (host.domain.tld) als Hostname, wenn Sie gefragt werden. -

      ./generate_config.sh
      -

      +./generate_config.sh

      4. Ändern Sie die Konfiguration, wenn Sie das wollen oder müssen. -

      nano mailcow.conf
      -
      +nano mailcow.conf Wenn Sie planen, einen Reverse Proxy zu verwenden, können Sie zum Beispiel HTTPS an 127.0.0.1 auf Port 8443 und HTTP an 127.0.0.1 auf Port 8080 binden.

      Möglicherweise müssen Sie einen vorinstallierten MTA stoppen, der Port 25/tcp blockiert. Siehe dieses Kapitel, um zu erfahren, wie man Postfix rekonfiguriert, um nach einer erfolgreichen Installation neben mailcow laufen zu lassen.

      Einige Updates modifizieren mailcow.conf und fügen neue Parameter hinzu. Es ist schwer, in der Dokumentation den Überblick zu behalten. Bitte überprüfen Sie deren Beschreibung und fragen Sie, wenn Sie unsicher sind, in den bekannten Kanälen nach Rat.

      @@ -2438,20 +2439,18 @@ Wenn Sie planen, einen Reverse Proxy zu verwenden, können Sie zum Beispiel HTTP

      Wenn Sie auf Probleme und seltsame Phänomene stoßen, überprüfen Sie bitte Ihre MTU.

      Bearbeiten Sie docker-compose.yml und ändern Sie die Netzwerkeinstellungen entsprechend Ihrer MTU. Fügen Sie den neuen Parameter driver_opts wie folgt hinzu: -

      networks:
      +networks:
         mailcow-network:
           ...
           driver_opts:
             com.docker.network.driver.mtu: 1450
      -    ...
      -

      + ...

      4.2. Benutzer ohne ein IPv6-aktiviertes Netzwerk auf ihrem Hostsystem:

      Einschalten von IPv6. Endlich.

      Wenn Sie kein IPv6-fähiges Netzwerk auf Ihrem Host haben und Sie sich nicht um ein besseres Internet kümmern (hehe), ist es empfehlenswert, IPv6 für das mailcow-Netzwerk zu deaktivieren, um unvorhergesehene Probleme zu vermeiden.

      5. LAden Sie die Images herunter und führen Sie die Compose-Datei aus. Der Parameter -d wird mailcow: dockerized starten: -

      docker-compose pull
      -docker-compose up -d
      -

      +docker-compose pull +docker-compose up -d

      Geschafft!

      Sie können nun auf https://${MAILCOW_HOSTNAME} mit den Standard-Zugangsdaten admin + Passwort moohoo zugreifen.

      @@ -2579,7 +2578,7 @@ docker-compose up -d - + diff --git a/de/i_u_m/i_u_m_migration/index.html b/de/i_u_m/i_u_m_migration/index.html index 1bd41c63d..9e7d67218 100644 --- a/de/i_u_m/i_u_m_migration/index.html +++ b/de/i_u_m/i_u_m_migration/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,8 +2380,6 @@ -

      Migration

      -

      Warning

      Diese Anleitung geht davon aus, dass Sie beabsichtigen, einen bestehenden Mailcow-Server (Quelle) auf einen brandneuen, leeren Server (Ziel) zu migrieren. Sie kümmert sich nicht um die Erhaltung bestehender Daten auf dem Zielserver und löscht alles innerhalb von /var/lib/docker/volumes und somit alle Docker-Volumes, die Sie bereits eingerichtet haben.

      @@ -2385,45 +2392,37 @@ Installieren Sie
      Docker und Docker Compose auf Ihrem neuen Server.

      Schnelle Installation für die meisten Betriebssysteme:

        -
      • -

        Docker -

        curl -sSL https://get.docker.com/ | CHANNEL=stable sh
        -# Nachdem der Installationsprozess abgeschlossen ist, müssen Sie den Dienst aktivieren und sicherstellen, dass er gestartet ist (z. B. CentOS 7)
        -systemctl enable docker.service
        -

        -
      • -
      • -

        docker-compose -

        curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose
        -chmod +x /usr/local/bin/docker-compose
        -

        -
      • +
      • Docker +``` +curl -sSL https://get.docker.com/ | CHANNEL=stable sh
      • +
      +

      Nachdem der Installationsprozess abgeschlossen ist, müssen Sie den Dienst aktivieren und sicherstellen, dass er gestartet ist (z. B. CentOS 7)

      +

      systemctl enable docker.service +```

      +
        +
      • docker-compose +curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose

      Bitte verwenden Sie die neueste verfügbare Docker-Engine und nicht die Engine, die mit Ihrem Distros-Repository ausgeliefert wird.

      2. Stoppen Sie Docker und stellen Sie sicher, dass Docker gestoppt wurde: -

      systemctl stop docker.service
      -systemctl status docker.service
      -

      +systemctl stop docker.service +systemctl status docker.service

      3. Führen Sie die folgenden Befehle auf dem Quellcomputer aus (achten Sie darauf, die abschließenden Schrägstriche im ersten Pfadparameter wie unten gezeigt hinzuzufügen!) - WARNUNG: Dieser Befehl löscht alles, was bereits unter /var/lib/docker/volumes auf dem Zielrechner existiert: -

      rsync -aHhP --numeric-ids --delete /opt/mailcow-dockerized/ root@target-machine.example.com:/opt/mailcow-dockerized
      -rsync -aHhP --numeric-ids --delete /var/lib/docker/volumes/ root@target-machine.example.com:/var/lib/docker/volumes
      -

      +rsync -aHhP --numeric-ids --delete /opt/mailcow-dockerized/ root@target-machine.example.com:/opt/mailcow-dockerized +rsync -aHhP --numeric-ids --delete /var/lib/docker/volumes/ root@target-machine.example.com:/var/lib/docker/volumes

      4. Schalten Sie mailcow ab und stoppen Sie Docker auf dem Quellrechner. -

      cd /opt/mailcow-dockerized
      +cd /opt/mailcow-dockerized
       docker-compose herunterfahren
      -systemctl stop docker.service
      -

      +systemctl stop docker.service

      **Wiederholen Sie Schritt 3 mit denselben Befehlen. Dies wird viel schneller gehen als beim ersten Mal.

      6. Wechseln Sie auf den Zielrechner und starten Sie Docker. -

      systemctl start docker.service
      -

      +systemctl start docker.service

      7. Ziehen Sie nun die mailcow Docker-Images auf den Zielrechner. -

      cd /opt/mailcow-dockerized
      -docker-compose pull
      -

      +cd /opt/mailcow-dockerized +docker-compose pull

      8. Starten Sie den gesamten mailcow-Stack und alles sollte fertig sein! -

      docker-compose up -d
      -

      +docker-compose up -d

      9. Zum Schluss ändern Sie Ihre DNS-Einstellungen so, dass sie auf den Zielserver zeigen.


      @@ -2544,7 +2543,7 @@ docker-compose pull - + diff --git a/de/i_u_m/i_u_m_update/index.html b/de/i_u_m/i_u_m_update/index.html index 1834d7488..b25c593da 100644 --- a/de/i_u_m/i_u_m_update/index.html +++ b/de/i_u_m/i_u_m_update/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -419,6 +419,82 @@ +
    + + + + +
  • + + Optionen können kombiniert werden + + +
  • + +
  • + + - Prüft auf Updates und zeigt Änderungen an + + +
  • + +
  • + + Versuchen Sie nicht, docker-compose zu aktualisieren, stellen Sie sicher, dass Sie die neueste verfügbare Version von docker-compose verwenden + + +
  • + +
  • + + - Starten Sie mailcow nicht, nachdem Sie ein Update durchgeführt haben + + +
  • + +
  • + + - Überspringt den ICMP Check auf die öffentlichen DNS Resolver (Bitte nur nutzen, wenn keinerlei ICMP Verbindungen von und zur mailcow erlaubt sind) + + +
  • + +
  • + + - Erzwinge Update (unbeaufsichtigt, aber nicht unterstützt, Benutzung auf eigenes Risiko) + + +
  • + +
  • + + - Garbage Collector ausführen, um alte Image-Tags zu bereinigen und beenden + + +
  • + +
  • + + - Update mit der Merge-Strategie-Option "ours" statt "theirs" + + +
  • + +
  • + + Dies wird Konflikte beim Zusammenführen zugunsten Ihrer lokalen Änderungen lösen und sollte vermieden werden. Lokale Änderungen werden immer beibehalten, es sei denn, wir haben auch die Datei XY geändert. + + +
  • + +
  • + + - Nicht aktualisieren, nur holen von Docker Images + + + + +
  • + +
  • + + Ersetzen Sie die Commit-ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab durch Ihre ID + + + - -
  • - -
  • +
  • Update-Zyklus +
  • + + + + @@ -2451,6 +2540,82 @@ + + + + + +
  • + + Optionen können kombiniert werden + + +
  • + +
  • + + - Prüft auf Updates und zeigt Änderungen an + + +
  • + +
  • + + Versuchen Sie nicht, docker-compose zu aktualisieren, stellen Sie sicher, dass Sie die neueste verfügbare Version von docker-compose verwenden + + +
  • + +
  • + + - Starten Sie mailcow nicht, nachdem Sie ein Update durchgeführt haben + + +
  • + +
  • + + - Überspringt den ICMP Check auf die öffentlichen DNS Resolver (Bitte nur nutzen, wenn keinerlei ICMP Verbindungen von und zur mailcow erlaubt sind) + + +
  • + +
  • + + - Erzwinge Update (unbeaufsichtigt, aber nicht unterstützt, Benutzung auf eigenes Risiko) + + +
  • + +
  • + + - Garbage Collector ausführen, um alte Image-Tags zu bereinigen und beenden + + +
  • + +
  • + + - Update mit der Merge-Strategie-Option "ours" statt "theirs" + + +
  • + +
  • + + Dies wird Konflikte beim Zusammenführen zugunsten Ihrer lokalen Änderungen lösen und sollte vermieden werden. Lokale Änderungen werden immer beibehalten, es sei denn, wir haben auch die Datei XY geändert. + + +
  • + +
  • + + - Nicht aktualisieren, nur holen von Docker Images + + + + +
  • + +
  • + + Ersetzen Sie die Commit-ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab durch Ihre ID + + + - -
  • - -
  • +
  • Update-Zyklus +
  • + + + + @@ -2502,60 +2680,50 @@ -

    Update

    -

    Automatische Aktualisierung

    Ein Update-Skript in Ihrem mailcow-dockerized Verzeichnis kümmert sich um Updates.

    Aber benutzen Sie es mit Bedacht! Wenn Sie denken, dass Sie viele Änderungen am mailcow-Code vorgenommen haben, sollten Sie die manuelle Update-Anleitung unten verwenden.

    Führen sie das Update-Skript aus: -

    ./update.sh
    -

    +./update.sh

    Wenn es nötig ist, wird es Sie fragen, wie Sie fortfahren möchten. Merge-Fehler werden gemeldet. Einige kleinere Konflikte werden automatisch korrigiert (zugunsten des mailcow: dockerized repository code).

    Optionen

    -
    # Optionen können kombiniert werden
    -
    -# - Prüft auf Updates und zeigt Änderungen an
    -./update.sh --check
    -
    -# Versuchen Sie nicht, docker-compose zu aktualisieren, **stellen Sie sicher, dass Sie die neueste verfügbare Version von docker-compose verwenden**
    -./update.sh --no-update-compose
    -
    -# - Starten Sie mailcow nicht, nachdem Sie ein Update durchgeführt haben
    -./update.sh --skip-start
    -
    -# - Überspringt den ICMP Check auf die öffentlichen DNS Resolver (Bitte nur nutzen, wenn keinerlei ICMP Verbindungen von und zur mailcow erlaubt sind)
    -./update.sh --skip-ping-check
    -
    -# - Erzwinge Update (unbeaufsichtigt, aber nicht unterstützt, Benutzung auf eigenes Risiko)
    -./update.sh --force
    -
    -# - Garbage Collector ausführen, um alte Image-Tags zu bereinigen und beenden
    -./update.sh --gc
    -
    -# - Update mit der Merge-Strategie-Option "ours" statt "theirs"
    -# Dies wird **Konflikte** beim Zusammenführen zugunsten Ihrer lokalen Änderungen lösen und sollte vermieden werden. Lokale Änderungen werden immer beibehalten, es sei denn, wir haben auch die Datei XY geändert.
    -./update.sh --ours
    -
    -# - Nicht aktualisieren, nur holen von Docker Images
    -./update.sh --prefetch
    -
    +

    ```

    +

    Optionen können kombiniert werden

    +

    - Prüft auf Updates und zeigt Änderungen an

    +

    ./update.sh --check

    +

    Versuchen Sie nicht, docker-compose zu aktualisieren, stellen Sie sicher, dass Sie die neueste verfügbare Version von docker-compose verwenden

    +

    ./update.sh --no-update-compose

    +

    - Starten Sie mailcow nicht, nachdem Sie ein Update durchgeführt haben

    +

    ./update.sh --skip-start

    +

    - Überspringt den ICMP Check auf die öffentlichen DNS Resolver (Bitte nur nutzen, wenn keinerlei ICMP Verbindungen von und zur mailcow erlaubt sind)

    +

    ./update.sh --skip-ping-check

    +

    - Erzwinge Update (unbeaufsichtigt, aber nicht unterstützt, Benutzung auf eigenes Risiko)

    +

    ./update.sh --force

    +

    - Garbage Collector ausführen, um alte Image-Tags zu bereinigen und beenden

    +

    ./update.sh --gc

    +

    - Update mit der Merge-Strategie-Option "ours" statt "theirs"

    +

    Dies wird Konflikte beim Zusammenführen zugunsten Ihrer lokalen Änderungen lösen und sollte vermieden werden. Lokale Änderungen werden immer beibehalten, es sei denn, wir haben auch die Datei XY geändert.

    +

    ./update.sh --ours

    +

    - Nicht aktualisieren, nur holen von Docker Images

    +

    ./update.sh --prefetch +```

    Ich habe vergessen, was ich vor dem Ausführen von update.sh geändert habe.

    Siehe git log --pretty=oneline | grep -i "before update", Sie werden eine Ausgabe ähnlich dieser haben:

    -
    22cd00b5e28893ef9ddef3c2b5436453cc5223ab Before update on 2020-09-28_19_25_45
    -dacd4fb9b51e9e1c8a37d84485b92ffaf6c59353 Before update on 2020-08-07_13_31_31
    -
    +

    22cd00b5e28893ef9ddef3c2b5436453cc5223ab Before update on 2020-09-28_19_25_45 +dacd4fb9b51e9e1c8a37d84485b92ffaf6c59353 Before update on 2020-08-07_13_31_31

    Führen Sie git diff 22cd00b5e28893ef9ddef3c2b5436453cc5223ab aus, um zu sehen, was sich geändert hat.

    Kann ich ein Rollback durchführen?

    Ja.

    Siehe das obige Thema, anstelle eines Diffs führen Sie checkout aus:

    -
    docker-compose down
    -# Ersetzen Sie die Commit-ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab durch Ihre ID
    -git checkout 22cd00b5e28893ef9ddef3c2b5436453cc5223ab
    +

    ``` +docker-compose down

    +

    Ersetzen Sie die Commit-ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab durch Ihre ID

    +

    git checkout 22cd00b5e28893ef9ddef3c2b5436453cc5223ab docker-compose pull docker-compose up -d -

    +```

    Hooks

    Sie können sich in den Update-Mechanismus einklinken, indem Sie Skripte namens pre_commit_hook.sh und post_commit_hook.sh zu Ihrem mailcows-Root-Verzeichnis hinzufügen. Siehe hier für weitere Details.

    Update-Zyklus

    @@ -2683,7 +2851,7 @@ docker-compose up -d - + diff --git a/de/index.html b/de/index.html index 40c946555..ee3776b11 100644 --- a/de/index.html +++ b/de/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2706,7 +2706,7 @@ Jeder Container repräsentiert eine einzelne Anwendung.

    - + diff --git a/de/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html b/de/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html index 170b5ae10..9bc69da5e 100644 --- a/de/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html +++ b/de/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2494,21 +2494,20 @@
  • Sie brauchen your_id von den Downloadlinks. Diese sind pro User individuell.
  • Fügen Sie diese wie folgt in die data/conf/clamav/freshclam.conf ein und ersetzen Sie den your_id Teil mit Ihrer ID: -

    DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfo.hdb
    +DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfo.hdb
     DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfo.ign2
     DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/javascript.ndb
     DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/spam_marketing.ndb
     DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfohtml.hdb
     DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfoascii.hdb
    -DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfopdf.hdb
    -

    +DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfopdf.hdb

  • Bei den kostenlosen SecuriteInfo Datenbanken ist die Download-Geschwindigkeit auf 300 kB/s begrenzt. Ändern Sie in data/conf/clamav/freshclam.conf den Standardwert ReceiveTimeout 20 auf ReceiveTimeout 90 (Zeitangabe in Sekunden), da ansonsten einige der Datenbank-Downloads aufgrund ihrer Größe abbrechen können.

  • Passen Sie data/conf/clamav/clamd.conf mit den folgenden Einstellungen an: -

    DetectPUA yes
    +DetectPUA yes
     ExcludePUA PUA.Win.Packer
     ExcludePUA PUA.Win.Trojan.Packed
     ExcludePUA PUA.Win.Trojan.Molebox
    @@ -2520,12 +2519,11 @@ MaxRecursion 40
     MaxEmbeddedPE 100M
     MaxHTMLNormalize 50M
     MaxScriptNormalize 50M
    -MaxZipTypeRcg 50M
    -

    +MaxZipTypeRcg 50M

  • Starten Sie den ClamAV Container neu: -
    docker-compose restart clamd-mailcow
    -
  • +bash +docker-compose restart clamd-mailcow

    Bitte beachten Sie:

      @@ -2537,14 +2535,13 @@ MaxZipTypeRcg 50M

      InterServer Datenbanken aktivieren

      1. Fügen Sie folgendes in data/conf/clamav/freshclam.conf ein: -
        DatabaseCustomURL http://sigs.interserver.net/interserver256.hdb
        +DatabaseCustomURL http://sigs.interserver.net/interserver256.hdb
         DatabaseCustomURL http://sigs.interserver.net/interservertopline.db
         DatabaseCustomURL http://sigs.interserver.net/shell.ldb
        -DatabaseCustomURL http://sigs.interserver.net/whitelist.fp
        -
      2. +DatabaseCustomURL http://sigs.interserver.net/whitelist.fp
      3. Starten Sie den ClamAV Container neu: -
        docker-compose restart clamd-mailcow
        -
      4. +bash +docker-compose restart clamd-mailcow

      @@ -2665,7 +2662,7 @@ DatabaseCustomURL http://sigs.interserver.net/whitelist.fp - + diff --git a/de/manual-guides/ClamAV/u_e-clamav-whitelist/index.html b/de/manual-guides/ClamAV/u_e-clamav-whitelist/index.html index a00f94f15..c63f3aa90 100644 --- a/de/manual-guides/ClamAV/u_e-clamav-whitelist/index.html +++ b/de/manual-guides/ClamAV/u_e-clamav-whitelist/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1870,6 +1870,13 @@ Whitelist für bestimmte ClamAV-Signaturen + + +
    • + + docker-compose exec redis-mailcow /bin/sh + +
    @@ -2402,6 +2409,13 @@ Whitelist für bestimmte ClamAV-Signaturen + + +
  • + + docker-compose exec redis-mailcow /bin/sh + +
  • @@ -2422,26 +2436,25 @@ -

    Whitelist

    -

    Whitelist für bestimmte ClamAV-Signaturen

    Es kann vorkommen, dass legitime (saubere) Mails von ClamAV blockiert werden (Rspamd markiert die Mail mit VIRUS_FOUND). So werden beispielsweise interaktive PDF-Formularanhänge standardmäßig blockiert, da der eingebettete Javascript-Code für schädliche Zwecke verwendet werden könnte. Überprüfen Sie dies anhand der clamd-Protokolle, z.B.:

    -
    docker-compose logs clamd-mailcow | grep "FOUND"
    -
    +

    bash +docker-compose logs clamd-mailcow | grep "FOUND"

    Diese Zeile bestätigt, dass ein solcher identifiziert wurde:

    -
    clamd-mailcow_1 | Sat Sep 28 07:43:24 2019 -> instream(local): PUA.Pdf.Trojan.EmbeddedJavaScript-1(e887d2ac324ce90750768b86b63d0749:363325) FOUND
    -
    +

    text +clamd-mailcow_1 | Sat Sep 28 07:43:24 2019 -> instream(local): PUA.Pdf.Trojan.EmbeddedJavaScript-1(e887d2ac324ce90750768b86b63d0749:363325) FOUND

    Um diese spezielle Signatur auf die Whitelist zu setzen (und den Versand dieses Dateityps im Anhang zu ermöglichen), fügen Sie sie der ClamAV-Signatur-Whitelist-Datei hinzu:

    -
    echo 'PUA.Pdf.Trojan.EmbeddedJavaScript-1' >> data/conf/clamav/whitelist.ign2
    -
    +

    bash +echo 'PUA.Pdf.Trojan.EmbeddedJavaScript-1' >> data/conf/clamav/whitelist.ign2

    Dann starten Sie den clamd-mailcow Service Container in der mailcow UI oder mit docker-compose neu:

    -
    docker-compose restart clamd-mailcow
    -
    +

    bash +docker-compose restart clamd-mailcow

    Bereinigen Sie zwischengespeicherte ClamAV-Ergebnisse in Redis:

    -
    # docker-compose exec redis-mailcow /bin/sh
    -/data # redis-cli KEYS rs_cl* | xargs redis-cli DEL
    +

    ```

    +

    docker-compose exec redis-mailcow /bin/sh

    +

    /data # redis-cli KEYS rs_cl* | xargs redis-cli DEL /data # exit -

    +```


    @@ -2561,7 +2574,7 @@ - + diff --git a/de/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html b/de/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html index d66a571b6..ad6e15c02 100644 --- a/de/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html +++ b/de/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,14 +2376,11 @@

    Dockerfiles anpassen

    Sie müssen die Override-Datei mit den entsprechenden Build-Tags in den mailcow: dockerized Root-Ordner (d.h. /opt/mailcow-dockerized) kopieren:

    -
    cp helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml docker-compose.override.yml
    -
    +

    cp helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml docker-compose.override.yml

    Nehmen Sie Ihre Änderungen in data/Dockerfiles/$service vor und erstellen Sie das Image lokal:

    -
    docker build data/Dockerfiles/service -t mailcow/$service
    -
    +

    docker build data/Dockerfiles/service -t mailcow/$service

    Nun werden die geänderten Container automatisch neu erstellt:

    -
    docker-compose up -d
    -
    +

    docker-compose up -d


    @@ -2503,7 +2500,7 @@ - + diff --git a/de/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html b/de/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html index 561fc2aeb..336a62c22 100644 --- a/de/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html +++ b/de/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,8 +2376,7 @@

    Docker Compose Bash Completion

    Um eine schöne Bash-Vervollständigung in Ihren Containern zu erhalten, führen Sie einfach das Folgende aus:

    -
    curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
    -
    +

    curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose


    @@ -2497,7 +2496,7 @@ - + diff --git a/de/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html b/de/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html index 214eeb8f5..a17da099d 100644 --- a/de/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html +++ b/de/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,8 +2377,7 @@

    Am 17. August haben wir die Möglichkeit, mit "jedem" oder "allen authentifizierten Benutzern" zu teilen, standardmäßig deaktiviert.

    Diese Funktion kann wieder aktiviert werden, indem ACL_ANYONE auf allow in mailcow.conf gesetzt wird:

    -
    ACL_ANYONE=allow
    -
    +

    ACL_ANYONE=allow

    Wenden Sie die Änderungen an, indem Sie docker-compose up -d ausführen.


    @@ -2499,7 +2498,7 @@ - + diff --git a/de/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html b/de/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html index 225d9266f..211b7b242 100644 --- a/de/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html +++ b/de/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2496,7 +2496,7 @@ - + diff --git a/de/manual-guides/Dovecot/u_e-dovecot-expunge/index.html b/de/manual-guides/Dovecot/u_e-dovecot-expunge/index.html index 842542204..1186296f2 100644 --- a/de/manual-guides/Dovecot/u_e-dovecot-expunge/index.html +++ b/de/manual-guides/Dovecot/u_e-dovecot-expunge/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1592,6 +1592,33 @@ + + + + + +
  • + + !/bin/bash + + +
  • + +
  • + + Pfad zu mailcow-dockerized, z.B. /opt/mailcow-dockerized + + +
  • + +
  • + + Jeden Tag um 04:00 Uhr morgens ausführen. + + + + +
  • + +
  • + + !/bin/bash + + +
  • + +
  • + + Pfad zu mailcow-dockerized, z.B. /opt/mailcow-dockerized + + +
  • + +
  • + + Jeden Tag um 04:00 Uhr morgens ausführen. + + + + +
  • + +
  • + + Einzelbenutzer + + +
  • + +
  • + + alle Benutzer + + +
  • + +
  • + + einzelner Benutzer + + +
  • + +
  • + + alle Benutzer, aber offensichtlich langsamer und gefährlicher + + + + +
  • + +
  • + + Einzelbenutzer + + +
  • + +
  • + + alle Benutzer + + +
  • + +
  • + + einzelner Benutzer + + +
  • + +
  • + + alle Benutzer, aber offensichtlich langsamer und gefährlicher + + +
  • @@ -2373,37 +2382,34 @@ -

    Mail crypt

    -

    Die Mails werden komprimiert (lz4) und verschlüsselt gespeichert. Das Schlüsselpaar ist in crypt-vol-1 zu finden.

    Wenn Sie vorhandene maildir-Dateien entschlüsseln/verschlüsseln wollen, können Sie das folgende Skript auf eigene Gefahr verwenden:

    Rufen Sie Dovecot auf, indem Sie docker-compose exec dovecot-mailcow /bin/bash im mailcow-dockerisierten Verzeichnis ausführen.

    -
    # Entschlüsseln Sie /var/vmail
    -find /var/vmail/ -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do
    -if [[ $(head -c7 "$file") == "CRYPTED" ]]; then
    +

    ```

    +

    Entschlüsseln Sie /var/vmail

    +

    find /var/vmail/ -type f -regextype egrep -regex '.S=.W=.*' | while read -r file; do +if [[ $(head -c7 "$file") == "CRYPTED" ]]; then doveadm fs get compress lz4:0:crypt:private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ - "$file" > "/tmp/$(basename "$file")" - if [[ -s "/tmp/$(basename "$file")" ]]; then - chmod 600 "/tmp/$(basename "$file")" - chown 5000:5000 "/tmp/$(basename "$file")" - mv "/tmp/$(basename "$file")" "$file" + "$file" > "/tmp/$(basename "$file")" + if [[ -s "/tmp/$(basename "$file")" ]]; then + chmod 600 "/tmp/$(basename "$file")" + chown 5000:5000 "/tmp/$(basename "$file")" + mv "/tmp/$(basename "$file")" "$file" else - rm "/tmp/$(basename "$file")" + rm "/tmp/$(basename "$file")" fi fi -done - - -# Verschlüsseln von /var/vmail -find /var/vmail/ -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do -if [[ $(head -c7 "$file") != "CRYPTED" ]]; then +done

    +

    Verschlüsseln von /var/vmail

    +

    find /var/vmail/ -type f -regextype egrep -regex '.S=.W=.*' | while read -r file; do +if [[ $(head -c7 "$file") != "CRYPTED" ]]; then doveadm fs put crypt private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ - "$file" "$file" - chmod 600 "$file" - chown 5000:5000 "$file" + "$file" "$file" + chmod 600 "$file" + chown 5000:5000 "$file" fi done -

    +```


    @@ -2523,7 +2529,7 @@ done - + diff --git a/de/manual-guides/Dovecot/u_e-dovecot-more/index.html b/de/manual-guides/Dovecot/u_e-dovecot-more/index.html index 51cd155b0..12e2b9b48 100644 --- a/de/manual-guides/Dovecot/u_e-dovecot-more/index.html +++ b/de/manual-guides/Dovecot/u_e-dovecot-more/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2442,25 +2442,19 @@

    doveadm quota

    Die Befehle quota get und quota recalc1 werden verwendet, um die Quota-Nutzung des aktuellen Benutzers anzuzeigen oder neu zu berechnen. Die angezeigten Werte sind in Kilobytes.

    Um den aktuellen Quota-Status für einen Benutzer / eine Mailbox aufzulisten, tun Sie folgendes:

    -
    doveadm quota get -u 'mailbox@example.org'
    -
    +

    doveadm quota get -u 'mailbox@example.org'

    Um den Quota-Speicherwert für alle Benutzer aufzulisten, tun Sie folgendes:

    -
    doveadm quota get -A |grep "STORAGE"
    -
    +

    doveadm quota get -A |grep "STORAGE"

    Berechnen Sie die Quota-Nutzung eines einzelnen Benutzers neu:

    -
    doveadm quota recalc -u 'mailbox@example.org'
    -
    +

    doveadm quota recalc -u 'mailbox@example.org'

    Der Befehl doveadm search2 wird verwendet, um Nachrichten zu finden, die Ihrer Anfrage entsprechen. Er kann den Benutzernamen, die Mailbox-GUID / -UID und die Nachrichten-GUIDs / -UIDs zurückgeben.

    Um die Anzahl der Nachrichten im .Trash Ordner eines Benutzers zu sehen:

    -
    doveadm search -A mailbox 'Trash' | awk '{print $1}' | sort | uniq -c
    -
    +

    doveadm search -A mailbox 'Trash' | awk '{print $1}' | sort | uniq -c

    Alle Nachrichten im Postfach eines Benutzers anzeigen, die älter als 90 Tage sind:

    -
    doveadm search -u 'mailbox@example.org' mailbox 'INBOX' savedbefore 90d
    -
    +

    doveadm search -u 'mailbox@example.org' mailbox 'INBOX' savedbefore 90d

    Zeige alle Nachrichten in beliebigen Ordnern, die älter sind als 30 Tage für mailbox@example.org:

    -
    doveadm search -u 'mailbox@example.org' mailbox "*" savedbefore 30d
    -
    +

    doveadm search -u 'mailbox@example.org' mailbox "*" savedbefore 30d


      @@ -2591,7 +2585,7 @@ - + diff --git a/de/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html b/de/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html index 860260bcd..088716da5 100644 --- a/de/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html +++ b/de/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2426,28 +2426,25 @@

      Erstellen Sie einen neuen öffentlichen Namespace "Public" und eine Mailbox "Develcow" innerhalb dieses Namespaces:

      Bearbeiten oder erstellen Sie data/conf/dovecot/extra.conf, fügen Sie hinzu:

      -
      namespace {
      +

      namespace { type = public separator = / prefix = Public/ location = maildir:/var/vmail/public:INDEXPVT=~/public subscriptions = yes - mailbox "Develcow" { + mailbox "Develcow" { auto = subscribe } -} -

      +}

      :INDEXPVT=~/public kann weggelassen werden, wenn die Flags, die pro Benutzer gesehen werden, nicht gewünscht sind.

      Die neue Mailbox im öffentlichen Namensraum wird von den Benutzern automatisch abonniert.

      Um allen authentifizierten Benutzern vollen Zugriff auf das neue Postfach (nicht auf den gesamten Namespace) zu gewähren, führen Sie aus:

      -
      docker-compose exec dovecot-mailcow doveadm acl set -A "Public/Develcow" "authenticated" lookup read write write-seen write-deleted insert post delete expunge create
      -
      +

      docker-compose exec dovecot-mailcow doveadm acl set -A "Public/Develcow" "authenticated" lookup read write write-seen write-deleted insert post delete expunge create

      Passen Sie den Befehl an Ihre Bedürfnisse an, wenn Sie detailliertere Rechte pro Benutzer vergeben möchten (verwenden Sie z.B. -u user@domain anstelle von -A).

      Erlaube authentifizierten Benutzern den Zugriff auf den gesamten öffentlichen Namespace

      Um allen authentifizierten Benutzern vollen Zugriff auf den gesamten öffentlichen Namespace und seine Unterordner zu gewähren, erstellen Sie eine neue Datei dovecot-acl im Namespace-Stammverzeichnis:

      Öffnen/bearbeiten/erstellen Sie /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/public/dovecot-acl (passen Sie den Pfad entsprechend an), um die globale ACL-Datei mit dem folgenden Inhalt zu erstellen:

      -
      authenticated kxeilprwts
      -
      +

      authenticated kxeilprwts

      kxeilprwts" ist gleichbedeutend mit "lookup read write write-seen write-deleted insert post delete expunge create".

      Sie können doveadm acl set -u user@domain "Public/Develcow" user=user@domain lookup read verwenden, um den Zugriff für einen einzelnen Benutzer zu beschränken. Sie können es auch umdrehen und den Zugriff für alle Benutzer auf "lr" beschränken und nur einigen Benutzern vollen Zugriff gewähren.

      Siehe Dovecot ACL für weitere Informationen über ACL.

      @@ -2570,7 +2567,7 @@ - + diff --git a/de/manual-guides/Dovecot/u_e-dovecot-static_master/index.html b/de/manual-guides/Dovecot/u_e-dovecot-static_master/index.html index 6a796ca0e..457bdbbdc 100644 --- a/de/manual-guides/Dovecot/u_e-dovecot-static_master/index.html +++ b/de/manual-guides/Dovecot/u_e-dovecot-static_master/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2379,9 +2379,8 @@

      Das wird empfohlen und sollte nicht geändert werden.

      Wenn der Benutzer trotzdem statisch sein soll, geben Sie bitte zwei Variablen in mailcow.conf an.

      Beide Parameter dürfen nicht leer sein!

      -
      DOVECOT_MASTER_USER=mymasteruser
      -DOVECOT_MASTER_PASS=mysecretpass
      -
      +

      DOVECOT_MASTER_USER=mymasteruser +DOVECOT_MASTER_PASS=mysecretpass

      Führen Sie docker-compose up -d aus, um Ihre Änderungen zu übernehmen.

      Der statische Master-Benutzername wird zu DOVECOT_MASTER_USER@mailcow.local erweitert.

      Um sich als test@example.org anzumelden, würde dies test@example.org*mymasteruser@mailcow.local mit dem oben angegebenen Passwort entsprechen.

      @@ -2506,7 +2505,7 @@ Es wird kein Hauptbenutzer benötigt.

      - + diff --git a/de/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html b/de/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html index eb71fe33f..28925f45a 100644 --- a/de/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html +++ b/de/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2470,41 +2470,39 @@

      Neuere Docker-Versionen scheinen sich über bestehende Volumes zu beschweren. Man kann dies vorübergehend beheben, indem man das bestehende Volume entfernt und mailcow mit der Override-Datei startet. Aber es scheint nach einem Neustart problematisch zu sein (muss bestätigt werden).

    Ein einfacher, schmutziger, aber stabiler Workaround ist es, mailcow zu stoppen (docker-compose down), /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data zu entfernen und einen neuen Link zu Ihrem entfernten Dateisystem zu erstellen, zum Beispiel:

    -
    mv /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data_backup
    -ln -s /mnt/volume-xy/vmail_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data
    -
    +

    mv /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data_backup +ln -s /mnt/volume-xy/vmail_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data

    Starten Sie anschließend mailcow.


    Der "alte" Weg

    Wenn man einen anderen Ordner für das vmail-Volume verwenden möchte, kann man eine docker-compose.override.yml Datei erstellen und den folgenden Inhalt hinzufügen:

    -
    version: '2.1'
    +

    version: '2.1' volumes: vmail-vol-1: driver_opts: type: none device: /data/mailcow/vmail - o: bind -

    + o: bind

    Verschieben eines bestehenden vmail-Ordners:

    • Finden Sie den aktuellen vmail-Ordner anhand seines "Mountpoint"-Attributs: docker volume inspect mailcowdockerized_vmail-vol-1
    -
    [
    +

    hl_lines="10" +[ { - "CreatedAt": "2019-06-16T22:08:34+02:00", - "Driver": "local", - "Labels": { - "com.docker.compose.project": "mailcowdockerized", - "com.docker.compose.version": "1.23.2", - "com.docker.compose.volume": "vmail-vol-1" + "CreatedAt": "2019-06-16T22:08:34+02:00", + "Driver": "local", + "Labels": { + "com.docker.compose.project": "mailcowdockerized", + "com.docker.compose.version": "1.23.2", + "com.docker.compose.volume": "vmail-vol-1" }, - "Mountpoint": "/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data", - "Name": "mailcowdockerized_vmail-vol-1", - "Options": null, - "Scope": "local" + "Mountpoint": "/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data", + "Name": "mailcowdockerized_vmail-vol-1", + "Options": null, + "Scope": "local" } -] -

    +]

    • Kopieren Sie den Inhalt des Mountpoint-Ordners an den neuen Speicherort (z.B. /data/mailcow/vmail) mit cp -a, rsync -a oder einem ähnlichen, nicht strikten Kopierbefehl
    • Stoppen Sie mailcow durch Ausführen von docker-compose down aus Ihrem mailcow-Stammverzeichnis (z.B. /opt/mailcow-dockerized)
    • @@ -2631,7 +2629,7 @@ volumes: - + diff --git a/de/manual-guides/Nginx/u_e-nginx_custom/index.html b/de/manual-guides/Nginx/u_e-nginx_custom/index.html index c6747d867..c87c66443 100644 --- a/de/manual-guides/Nginx/u_e-nginx_custom/index.html +++ b/de/manual-guides/Nginx/u_e-nginx_custom/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2472,9 +2472,9 @@

      Neue Website

      Um persistente (über Updates) Sites zu erstellen, die von mailcow: dockerized gehostet werden, muss eine neue Site-Konfiguration in data/conf/nginx/ platziert werden:

      Eine gute Vorlage, um damit zu beginnen:

      -
      nano data/conf/nginx/my_custom_site.conf
      -
      -
      server {
      +

      nano data/conf/nginx/my_custom_site.conf

      +

      ``` hl_lines="16" +server { ssl_certificate /etc/ssl/mail/cert.pem; ssl_certificate_key /etc/ssl/mail/key.pem; ssl_protocols TLSv1.2 TLSv1.3; @@ -2489,29 +2489,27 @@ # Location: data/web root /web; # Location: data/web/mysite.com - #root /web/mysite.com - include /etc/nginx/conf.d/listen_plain.active; + #root /web/mysite.com + include /etc/nginx/conf.d/listen_plain.active; include /etc/nginx/conf.d/listen_ssl.active; server_name mysite.example.org; - server_tokens off; - - # This allows acme to be validated even with a different web root + server_tokens off;

      +

      # This allows acme to be validated even with a different web root location ^~ /.well-known/acme-challenge/ { - default_type "text/plain"; + default_type "text/plain"; rewrite /.well-known/acme-challenge/(.*) /$1 break; root /web/.well-known/acme-challenge/; - } - - if ($scheme = http) { + }

      +

      if ($scheme = http) { return 301 https://$server_name$request_uri; } } -

      +```

      Neue Website mit Proxy zu einem entfernten Location

      Ein weiteres Beispiel mit einer Reverse-Proxy-Konfiguration:

      -
      nano data/conf/nginx/my_custom_site.conf
      -
      -
      server {
      +

      nano data/conf/nginx/my_custom_site.conf

      +

      ``` hl_lines="16 28" +server { ssl_certificate /etc/ssl/mail/cert.pem; ssl_certificate_key /etc/ssl/mail/key.pem; ssl_protocols TLSv1.2 TLSv1.3; @@ -2526,20 +2524,17 @@ root /web; include /etc/nginx/conf.d/listen_plain.active; include /etc/nginx/conf.d/listen_ssl.active; - server_name example.domain.tld; - server_tokens off; - - location ^~ /.well-known/acme-challenge/ { + server_name example.domain.tld; + server_tokens off;

      +

      location ^~ /.well-known/acme-challenge/ { allow all; - default_type "text/plain"; - } - - if ($scheme = http) { + default_type "text/plain"; + }

      +

      if ($scheme = http) { return 301 https://$host$request_uri; - } - - location / { - proxy_pass http://service:3000/; + }

      +

      location / { + proxy_pass http://service:3000/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -2547,18 +2542,16 @@ client_max_body_size 0; } } -

      +```

      Konfig-Erweiterung in mailcows Nginx

      Der Dateiname, der für eine neue Site verwendet wird, ist nicht wichtig, solange der Dateiname eine .conf-Erweiterung trägt.

      Es ist auch möglich, die Konfiguration der Standarddatei site.conf Datei zu erweitern:

      -
      nano data/conf/nginx/site.my_content.custom
      -
      +

      nano data/conf/nginx/site.my_content.custom

      Dieser Dateiname muss keine ".conf"-Erweiterung haben, sondern folgt dem Muster site.*.custom, wobei * ein eigener Name ist.

      Wenn PHP in eine benutzerdefinierte Site eingebunden werden soll, verwenden Sie bitte den PHP-FPM-Listener auf phpfpm:9002 oder erstellen Sie einen neuen Listener in data/conf/phpfpm/php-fpm.d/pools.conf.

      Starten Sie Nginx neu (und PHP-FPM, falls ein neuer Listener erstellt wurde):

      -
      docker-compose restart nginx-mailcow
      -docker-compose restart php-fpm-mailcow
      -
      +

      docker-compose restart nginx-mailcow +docker-compose restart php-fpm-mailcow


      @@ -2678,7 +2671,7 @@ docker-compose restart php-fpm-mailcow - + diff --git a/de/manual-guides/Nginx/u_e-nginx_webmail-site/index.html b/de/manual-guides/Nginx/u_e-nginx_webmail-site/index.html index 393a19fda..f1bda3fcb 100644 --- a/de/manual-guides/Nginx/u_e-nginx_webmail-site/index.html +++ b/de/manual-guides/Nginx/u_e-nginx_webmail-site/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2378,7 +2378,8 @@

      WICHTIG: Diese Anleitung gilt nur für Konfigurationen, bei denen SNI nicht aktiviert ist. Wenn SNI aktiviert ist, muss der Zertifikatspfad angepasst werden. Etwas wie ssl_certificate,key /etc/ssl/mail/webmail.example.org/cert.pem,key.pem; wird genügen. Aber: Das Zertifikat sollte zuerst bezogen werden und erst wenn das Zertifikat existiert, sollte eine Site Config erstellt werden. Nginx wird nicht starten, wenn es das Zertifikat und den Schlüssel nicht finden kann.

      Um eine Subdomain webmail.example.org zu erstellen und sie auf SOGo umzuleiten, müssen Sie eine neue Nginx-Site erstellen. Achten Sie dabei auf "CHANGE_TO_MAILCOW_HOSTNAME"!

      nano data/conf/nginx/webmail.conf

      -
      server {
      +

      ``` hl_lines="9 17" +server { ssl_certificate /etc/ssl/mail/cert.pem; ssl_certificate_key /etc/ssl/mail/key.pem; index index.php index.html; @@ -2386,23 +2387,21 @@ root /web; include /etc/nginx/conf.d/listen_plain.active; include /etc/nginx/conf.d/listen_ssl.active; - server_name webmail.example.org; - server_tokens off; + server_name webmail.example.org; + server_tokens off; location ^~ /.well-known/acme-challenge/ { allow all; - default_type "text/plain"; + default_type "text/plain"; + }

      +

      location / { + return 301 https://CHANGE_TO_MAILCOW_HOSTNAME/SOGo; } - - location / { - return 301 https://CHANGE_TO_MAILCOW_HOSTNAME/SOGo; - } } -

      +```

      Speichern Sie und starten Sie Nginx neu: docker-compose restart nginx-mailcow.

      Öffnen Sie nun mailcow.conf und suchen Sie ADDITIONAL_SAN. Fügen Sie webmail.example.org zu diesem Array hinzu, verwenden Sie keine Anführungszeichen!

      -
      ADDITIONAL_SAN=webmail.example.org
      -
      +

      ADDITIONAL_SAN=webmail.example.org

      Führen Sie docker-compose up -d aus. Siehe "acme-mailcow" und "nginx-mailcow" Logs, wenn etwas fehlschlägt.


      @@ -2523,7 +2522,7 @@ Fügen Sie webmail.example.org zu diesem Array hinzu, verwenden Sie - + diff --git a/de/manual-guides/Postfix/u_e-postfix-attachment_size/index.html b/de/manual-guides/Postfix/u_e-postfix-attachment_size/index.html index b8d46451b..a5bd82e8a 100644 --- a/de/manual-guides/Postfix/u_e-postfix-attachment_size/index.html +++ b/de/manual-guides/Postfix/u_e-postfix-attachment_size/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,8 +2377,7 @@

      Öffnen Sie data/conf/postfix/extra.cf und setzen Sie das message_size_limit entsprechend in Bytes. Siehe main.cf für den Standardwert.

      Starten Sie Postfix neu:

      -
      docker-compose restart postfix-mailcow
      -
      +

      docker-compose restart postfix-mailcow


      @@ -2498,7 +2497,7 @@ - + diff --git a/de/manual-guides/Postfix/u_e-postfix-custom_transport/index.html b/de/manual-guides/Postfix/u_e-postfix-custom_transport/index.html index a16d86e44..908d9a161 100644 --- a/de/manual-guides/Postfix/u_e-postfix-custom_transport/index.html +++ b/de/manual-guides/Postfix/u_e-postfix-custom_transport/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2497,7 +2497,7 @@ - + diff --git a/de/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html b/de/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html index b5ce422c6..0f7902e2c 100644 --- a/de/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html +++ b/de/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2444,14 +2444,11 @@

      Veraltete Anleitung (NICHT FÜR NEUERE MAILCOWS VERWENDEN!)

      Diese Option ist keine Best-Practice und sollte nur verwendet werden, wenn es keine andere Möglichkeit gibt, das zu erreichen, was Sie erreichen wollen.

      Erstellen Sie einfach eine Datei data/conf/postfix/check_sasl_access und tragen Sie den folgenden Inhalt ein. Dieser Benutzer muss in Ihrer Installation existieren und muss sich vor dem Versenden von Mails authentifizieren. -

      user-to-allow-everything@example.com OK
      -

      +user-to-allow-everything@example.com OK

      Öffnen Sie data/conf/postfix/main.cf und suchen Sie smtpd_sender_restrictions. Fügen Sie check_sasl_access hash:/opt/postfix/conf/check_sasl_access wie folgt ein: -

      smtpd_sender_restrictions = check_sasl_access hash:/opt/postfix/conf/check_sasl_access reject_authenticated_sender_login_mismatch [...]
      -

      +smtpd_sender_restrictions = check_sasl_access hash:/opt/postfix/conf/check_sasl_access reject_authenticated_sender_login_mismatch [...]

      Postmap auf check_sasl_access ausführen:

      -
      docker-compose exec postfix-mailcow postmap /opt/postfix/conf/check_sasl_access
      -
      +

      docker-compose exec postfix-mailcow postmap /opt/postfix/conf/check_sasl_access

      Starten Sie den Postfix-Container neu.


      @@ -2572,7 +2569,7 @@ - + diff --git a/de/manual-guides/Postfix/u_e-postfix-extra_cf/index.html b/de/manual-guides/Postfix/u_e-postfix-extra_cf/index.html index ee4dc91a3..1eeee1833 100644 --- a/de/manual-guides/Postfix/u_e-postfix-extra_cf/index.html +++ b/de/manual-guides/Postfix/u_e-postfix-extra_cf/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2379,8 +2379,7 @@

      Postfix wird sich einmal nach dem Start von postfix-mailcow über doppelte Werte beschweren, dies ist beabsichtigt.

      Syslog-ng wurde so konfiguriert, dass es diese Warnungen ausblendet, während Postfix läuft, um die Log-Dateien nicht jedes Mal mit unnötigen Informationen zu spammen, wenn ein Dienst benutzt wird.

      Starten Sie postfix-mailcow neu, um Ihre Änderungen zu übernehmen:

      -
      docker-compose restart postfix-mailcow
      -
      +

      docker-compose restart postfix-mailcow


      @@ -2500,7 +2499,7 @@ - + diff --git a/de/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html b/de/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html index 41e8be319..4dfc613c0 100644 --- a/de/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html +++ b/de/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,13 +2376,11 @@

      Statistik mit pflogsumm

      Um pflogsumm mit dem Standard-Logging-Treiber zu verwenden, müssen wir postfix-mailcow über docker logs abfragen und die Ausgabe zu pflogsumm leiten:

      -
      docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | pflogsumm
      -
      +

      docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | pflogsumm

      Die obige Log-Ausgabe ist auf die letzten 24 Stunden beschränkt.

      Es ist auch möglich, einen täglichen pflogsumm-Bericht über cron zu erstellen. Erstellen Sie die Datei /etc/cron.d/pflogsumm mit dem folgenden Inhalt:

      -
      SHELL=/bin/bash
      -59 23 * * * root docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | /usr/sbin/pflogsumm -d today | mail -s "Postfix Report of $(date)" postmaster@example.net
      -
      +

      SHELL=/bin/bash +59 23 * * * root docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | /usr/sbin/pflogsumm -d today | mail -s "Postfix Report of $(date)" postmaster@example.net

      Um zu funktionieren muss ein lokaler Postfix auf dem Server installiert werden, welcher an den Postfix der mailcow relayed.

      Genauere Informationen lassen sich unter Sektion Post-Installationsaufgaben -> Lokaler MTA auf Dockerhost finden.

      Basierend auf den Postfix-Logs der letzten 24 Stunden sendet dieses Beispiel dann jeden Tag um 23:59:00 Uhr einen pflogsumm-Bericht an postmaster@example.net.

      @@ -2505,7 +2503,7 @@ - + diff --git a/de/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html b/de/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html index 611572e15..47c8613ab 100644 --- a/de/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html +++ b/de/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2373,19 +2382,18 @@ -

      IP in Postscreen auf die Whitelist setzen

      -

      IPs können in der Datei data/conf/postfix/custom_postscreen_whitelist.cidr aus dem Postscreen und damit auch aus den RBL-Prüfungen entfernt werden.

      Postscreen führt mehrere Prüfungen durch, um bösartige Absender zu identifizieren. In den meisten Fällen möchten Sie eine IP-Adresse auf die Whitelist setzen, um sie von der Suche nach einer schwarzen Liste auszuschließen.

      Das Format der Datei ist wie folgt

      CIDR ACTION

      Dabei steht CIDR für eine einzelne IP-Adresse oder einen IP-Bereich in CIDR-Notation und action entweder für "permit" oder "reject".

      Beispiel:

      -
      +```

      Die Datei wird spontan neu geladen, ein Neustart von Postfix ist nicht erforderlich.


      @@ -2506,7 +2514,7 @@ - + diff --git a/de/manual-guides/Postfix/u_e-postfix-relayhost/index.html b/de/manual-guides/Postfix/u_e-postfix-relayhost/index.html index cc0b74881..a361217ea 100644 --- a/de/manual-guides/Postfix/u_e-postfix-relayhost/index.html +++ b/de/manual-guides/Postfix/u_e-postfix-relayhost/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2606,7 +2606,7 @@ Beachten Sie, dass die Anmeldedaten im Klartext gespeichert werden.

      - + diff --git a/de/manual-guides/Postfix/u_e-postfix-trust_networks/index.html b/de/manual-guides/Postfix/u_e-postfix-trust_networks/index.html index c203d35c1..25ad2b717 100644 --- a/de/manual-guides/Postfix/u_e-postfix-trust_networks/index.html +++ b/de/manual-guides/Postfix/u_e-postfix-trust_networks/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2475,15 +2475,13 @@

      IPv4-Hosts/Subnetze

      Um das Subnetz 192.168.2.0/24 zu den vertrauenswürdigen Netzwerken hinzuzufügen, können Sie die folgende Konfiguration verwenden, abhängig von Ihren IPV4_NETWORK und IPV6_NETWORK Bereichen:

      Bearbeiten Sie data/conf/postfix/extra.cf:

      -
      mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 192.168.2.0/24
      -
      +

      mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 192.168.2.0/24

      Führen Sie docker-compose restart postfix-mailcow aus, um Ihre neuen Einstellungen zu übernehmen.

      IPv6-Hosts/Subnets

      Das Hinzufügen von IPv6-Hosts erfolgt auf die gleiche Weise wie bei IPv4, allerdings muss das Subnetz in eckige Klammern [] gesetzt und die Netzmaske angehängt werden.

      Um das Subnetz 2001:db8::/32 zu den vertrauenswürdigen Netzwerken hinzuzufügen, können Sie die folgende Konfiguration verwenden, abhängig von Ihren IPV4_NETWORK- und IPV6_NETWORK-Bereichen:

      Bearbeiten Sie data/conf/postfix/extra.cf:

      -
      mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 [2001:db8::]/32
      -
      +

      mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 [2001:db8::]/32

      Führen Sie docker-compose restart postfix-mailcow aus, um Ihre neuen Einstellungen zu übernehmen.

      Info

      @@ -2608,7 +2606,7 @@ - + diff --git a/de/manual-guides/Redis/u_e-redis/index.html b/de/manual-guides/Redis/u_e-redis/index.html index 06aba6f55..281bed216 100644 --- a/de/manual-guides/Redis/u_e-redis/index.html +++ b/de/manual-guides/Redis/u_e-redis/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1832,6 +1832,24 @@ +
    + + + + + + + + + +
  • + + docker-compose exec redis-mailcow redis-cli + + + -
  • - - - - @@ -2458,6 +2471,24 @@ + + + + + + + + + + +
  • + + docker-compose exec redis-mailcow redis-cli + + + -
  • - - - - @@ -2500,33 +2526,29 @@ -

    Redis

    -

    Redis wird als Key-Value-Speicher für die Einstellungen und Daten von rspamd und (einige von) mailcow verwendet. Wenn Sie mit Redis nicht vertraut sind, lesen Sie bitte die Einführung in Redis und besuchen Sie gegebenenfalls diese wunderbare Anleitung, um zu erfahren, wie man Redis benutzt.

    Client

    Um sich mit dem redis cli zu verbinden, führen Sie aus:

    -
    docker-compose exec redis-mailcow redis-cli
    -
    +

    docker-compose exec redis-mailcow redis-cli

    Fehlersuche

    Hier sind einige nützliche Befehle für den redis-cli zur Fehlersuche:

    MONITOR

    Überwacht alle vom Server empfangenen Anfragen in Echtzeit:

    -
    # docker-compose exec redis-mailcow redis-cli
    -127.0.0.1:6379> überwachen
    +

    ```

    +

    docker-compose exec redis-mailcow redis-cli

    +

    127.0.0.1:6379> überwachen OK -1494077286.401963 [0 172.22.1.253:41228] "SMEMBERS" "BAYES_SPAM_keys" -1494077288.292970 [0 172.22.1.253:41229] "SMEMBERS" "BAYES_SPAM_keys" +1494077286.401963 [0 172.22.1.253:41228] "SMEMBERS" "BAYES_SPAM_keys" +1494077288.292970 [0 172.22.1.253:41229] "SMEMBERS" "BAYES_SPAM_keys" [...] -

    +```

    SCHLÜSSEL (Keys)

    Ermittelt alle Schlüssel, die dem Muster entsprechen:

    -
    KEYS *
    -
    +

    KEYS *

    PING

    Testen Sie eine Verbindung:

    -
    127.0.0.1:6379> PING
    -PONG
    -
    +

    127.0.0.1:6379> PING +PONG

    Wenn Sie mehr wissen wollen, hier ist ein Cheat-Sheet.


    @@ -2647,7 +2669,7 @@ PONG - + diff --git a/de/manual-guides/Rspamd/u_e-rspamd/index.html b/de/manual-guides/Rspamd/u_e-rspamd/index.html index e3adc7302..ada4703bf 100644 --- a/de/manual-guides/Rspamd/u_e-rspamd/index.html +++ b/de/manual-guides/Rspamd/u_e-rspamd/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1844,52 +1844,146 @@
  • + + Ham + + +
  • + +
  • + + Spam + + + + +
  • + +
  • + + Es ist besser, Redis zu stoppen, bevor Sie die Datei kopieren. + + +
  • + +
  • + + Wir müssen zuerst das redis-cli eingeben: + + +
  • + +
  • + + In redis-cli: + + + +
  • + + oder: + + +
  • + +
  • + + docker-compose exec mysql-mailcow mysql -umailcow -p$DBPASS mailcow -e "delete from filterconf where option = 'highspamlevel' or option = 'lowspamlevel' and object = 'amp#111;amp#110;amp#108;amp#121;amp#45;amp#116;amp#104;amp#105;amp#115;amp#45;amp#109;amp#97;amp#105;amp#108;amp#98;amp#111;amp#120;amp#64;amp#101;amp#120;amp#97;amp#109;amp#112;amp#108;amp#101;amp#46;amp#111;amp#114;amp#103;';" + + + +
  • + + Unlink (verfügbar in Redis >=4.) löscht im Hintergrund + + + +
  • @@ -2478,52 +2572,146 @@
  • + + Ham + + +
  • + +
  • + + Spam + + + + +
  • + +
  • + + Es ist besser, Redis zu stoppen, bevor Sie die Datei kopieren. + + +
  • + +
  • + + Wir müssen zuerst das redis-cli eingeben: + + +
  • + +
  • + + In redis-cli: + + + +
  • + + oder: + + +
  • + +
  • + + docker-compose exec mysql-mailcow mysql -umailcow -p$DBPASS mailcow -e "delete from filterconf where option = 'highspamlevel' or option = 'lowspamlevel' and object = 'amp#111;amp#110;amp#108;amp#121;amp#45;amp#116;amp#104;amp#105;amp#115;amp#45;amp#109;amp#97;amp#105;amp#108;amp#98;amp#111;amp#120;amp#64;amp#101;amp#120;amp#97;amp#109;amp#112;amp#108;amp#101;amp#46;amp#111;amp#114;amp#103;';" + + + +
  • + + Unlink (verfügbar in Redis >=4.) löscht im Hintergrund + + + +
  • @@ -2544,8 +2732,6 @@ -

    Rspamd

    -

    Rspamd wird für die AV-Verarbeitung, DKIM-Signierung und SPAM-Verarbeitung verwendet. Es ist ein leistungsfähiges und schnelles Filtersystem. Für eine ausführlichere Dokumentation über Rspamd besuchen Sie bitte die [Rspamd Dokumentation] (https://rspamd.com/doc/index.html).

    Spam & Ham lernen

    Rspamd lernt, ob es sich um Spam oder Ham handelt, wenn Sie eine Nachricht in oder aus dem Junk-Ordner in ein anderes Postfach als den Papierkorb verschieben. @@ -2556,78 +2742,73 @@ Dies wird durch die Verwendung des Sieve-Plugins "sieve_imapsieve" und Parser-Sk

    Sie können auch die Web-UI von Rspamd verwenden, um Ham und/oder Spam zu lernen oder bestimmte Einstellungen von Rspamd anzupassen.

    Spam oder Ham aus bestehendem Verzeichnis lernen

    Sie können einen Einzeiler verwenden, um Mails im Klartextformat (unkomprimiert) zu lernen:

    -
    # Ham
    -for file in /my/folder/cur/*; do docker exec -i $(docker-compose ps -q rspamd-mailcow) rspamc learn_ham < $file; done
    -# Spam
    -for file in /my/folder/.Junk/cur/*; do docker exec -i $(docker-compose ps -q rspamd-mailcow) rspamc learn_spam < $file; done
    -
    +

    ```bash

    +

    Ham

    +

    for file in /my/folder/cur/*; do docker exec -i $(docker-compose ps -q rspamd-mailcow) rspamc learn_ham < $file; done

    +

    Spam

    +

    for file in /my/folder/.Junk/cur/*; do docker exec -i $(docker-compose ps -q rspamd-mailcow) rspamc learn_spam < $file; done +```

    Erwägen Sie, einen lokalen Ordner als neues Volume an rspamd-mailcow in docker-compose.yml anzuhängen und die gegebenen Dateien innerhalb des Containers zu lernen. Dies kann als Workaround verwendet werden, um komprimierte Daten mit zcat zu parsen. Beispiel:

    ``bash for file in /data/old_mail/.Junk/cur/*; do rspamc learn_spam < zcat $file; done -

    ### Gelernte Daten zurücksetzen (Bayes, Neural)
    -
    -Sie müssen die Schlüssel in Redis löschen, um die gelernten Daten zurückzusetzen, also erstellen Sie jetzt eine Kopie Ihrer Redis-Datenbank:
    -
    -**Backup Datenbank**
    -
    -```bash
    -# Es ist besser, Redis zu stoppen, bevor Sie die Datei kopieren.
    -cp /var/lib/docker/volumes/mailcowdockerized_redis-vol-1/_data/dump.rdb /root/
    -

    +```

    +

    Gelernte Daten zurücksetzen (Bayes, Neural)

    +

    Sie müssen die Schlüssel in Redis löschen, um die gelernten Daten zurückzusetzen, also erstellen Sie jetzt eine Kopie Ihrer Redis-Datenbank:

    +

    Backup Datenbank

    +

    ```bash

    +

    Es ist besser, Redis zu stoppen, bevor Sie die Datei kopieren.

    +

    cp /var/lib/docker/volumes/mailcowdockerized_redis-vol-1/_data/dump.rdb /root/ +```

    Bayes-Daten zurücksetzen

    -
    docker-compose exec redis-mailcow sh -c 'redis-cli --scan --pattern BAYES_* | xargs redis-cli del'
    -docker-compose exec redis-mailcow sh -c 'redis-cli --scan --pattern RS* | xargs redis-cli del'
    -
    +

    bash +docker-compose exec redis-mailcow sh -c 'redis-cli --scan --pattern BAYES_* | xargs redis-cli del' +docker-compose exec redis-mailcow sh -c 'redis-cli --scan --pattern RS* | xargs redis-cli del'

    Neurale Daten zurücksetzen

    -
    docker-compose exec redis-mailcow sh -c 'redis-cli --scan --pattern rn_* | xargs redis-cli del'
    -
    +

    bash +docker-compose exec redis-mailcow sh -c 'redis-cli --scan --pattern rn_* | xargs redis-cli del'

    Fuzzy-Daten zurücksetzen

    -
    # Wir müssen zuerst das redis-cli eingeben:
    -docker-compose exec redis-mailcow redis-cli
    -# In redis-cli:
    -127.0.0.1:6379> EVAL "for i, name in ipairs(redis.call('KEYS', ARGV[1])) do redis.call('DEL', name); end" 0 fuzzy*
    -
    +

    ```bash

    +

    Wir müssen zuerst das redis-cli eingeben:

    +

    docker-compose exec redis-mailcow redis-cli

    +

    In redis-cli:

    +

    127.0.0.1:6379> EVAL "for i, name in ipairs(redis.call('KEYS', ARGV[1])) do redis.call('DEL', name); end" 0 fuzzy* +```

    Info

    Wenn redis-cli sich beschwert über...

    -
    (error) ERR wrong number of arguments for 'del' command
    -
    +

    Text +(error) ERR wrong number of arguments for 'del' command

    ...das Schlüsselmuster nicht gefunden wurde und somit keine Daten zum Löschen vorhanden sind - ist es in Ordnung.

    CLI-Werkzeuge

    ``bash docker-compose exec rspamd-mailcow rspamc --help docker-compose exec rspamd-mailcow rspamadm --help -

    ## Greylisting deaktivieren
    -
    -Nur Nachrichten mit einer höheren Punktzahl werden als Greylisting betrachtet (soft rejected). Es ist schlechte Praxis, Greylisting zu deaktivieren.
    -
    -Sie können Greylisting serverweit durch Editieren deaktivieren:
    -
    -`{mailcow-dir}/data/conf/rspamd/local.d/greylist.conf`
    -
    -Fügen Sie die Zeile hinzu:
    -
    -```cpp
    -enabled = false;
    -

    +```

    +

    Greylisting deaktivieren

    +

    Nur Nachrichten mit einer höheren Punktzahl werden als Greylisting betrachtet (soft rejected). Es ist schlechte Praxis, Greylisting zu deaktivieren.

    +

    Sie können Greylisting serverweit durch Editieren deaktivieren:

    +

    {mailcow-dir}/data/conf/rspamd/local.d/greylist.conf

    +

    Fügen Sie die Zeile hinzu:

    +

    cpp +enabled = false;

    Speichern Sie die Datei und starten Sie "rspamd-mailcow" neu: docker-compose restart rspamd-mailcow

    Spamfilter-Schwellenwerte (global)

    Jeder Benutzer kann seine Spam-Bewertung individuell ändern. Um eine neue serverweite Grenze zu definieren, editieren Sie data/conf/rspamd/local.d/actions.conf:

    -
    reject = 15;
    -add_header = 8;
    -greylist = 7;
    -
    +

    cpp +reject = 15; +add_header = 8; +greylist = 7;

    Speichern Sie die Datei und starten Sie "rspamd-mailcow" neu: docker-compose restart rspamd-mailcow

    Bestehende Einstellungen der Benutzer werden nicht überschrieben!

    Um benutzerdefinierte Schwellenwerte zurückzusetzen, führen Sie aus:

    -
    source mailcow.conf
    -docker-compose exec mysql-mailcow mysql -umailcow -p$DBPASS mailcow -e "delete from filterconf where option = 'highspamlevel' or option = 'lowspamlevel';"
    -# oder:
    -# docker-compose exec mysql-mailcow mysql -umailcow -p$DBPASS mailcow -e "delete from filterconf where option = 'highspamlevel' or option = 'lowspamlevel' and object = 'only-this-mailbox@example.org';"
    -
    +

    ``` +source mailcow.conf +docker-compose exec mysql-mailcow mysql -umailcow -p$DBPASS mailcow -e "delete from filterconf where option = 'highspamlevel' or option = 'lowspamlevel';"

    +

    oder:

    +

    docker-compose exec mysql-mailcow mysql -umailcow -p$DBPASS mailcow -e "delete from filterconf where option = 'highspamlevel' or option = 'lowspamlevel' and object = 'only-this-mailbox@example.org';"

    +

    ```

    Benutzerdefinierte Ablehnungsnachrichten

    Die Standard-Spam-Reject-Meldung kann durch Hinzufügen einer neuen Datei data/conf/rspamd/override.d/worker-proxy.custom.inc mit dem folgenden Inhalt geändert werden:

    -
    reject_message = "Meine eigene Ablehnungsnachricht";
    -
    +

    reject_message = "Meine eigene Ablehnungsnachricht";

    Speichern Sie die Datei und starten Sie Rspamd neu: docker-compose restart rspamd-mailcow.

    Waehrend das oben genannte fuer abgelehnte Mails mit einem hohen Spam-Score funktioniert, ignorieren Prefilter-Aktionen diese Einstellung. Für diese Karten muss das Multimap-Modul in Rspamd angepasst werden:

      @@ -2638,48 +2819,45 @@ docker-compose exec mysql-mailcow mysql -umailcow -p$DBPASS mailcow -e "del

      Fügen Sie Ihre eigene Nachricht als neue Zeile hinzu:

    -
    GLOBAL_RCPT_BL {
    -  Typ = "rcpt";
    -  map = "${LOCAL_CONFDIR}/custom/global_rcpt_blacklist.map";
    +

    GLOBAL_RCPT_BL { + Typ = "rcpt"; + map = "${LOCAL_CONFDIR}/custom/global_rcpt_blacklist.map"; regexp = true; prefilter = true; - action = "reject"; - message = "Der Versand von E-Mails an diesen Empfänger ist durch postmaster@your.domain verboten"; -} -

    + action = "reject"; + message = "Der Versand von E-Mails an diesen Empfänger ist durch postmaster@your.domain verboten"; +}

    1. Speichern Sie die Datei und starten Sie Rspamd neu: docker-compose restart rspamd-mailcow.

    Verwerfen statt zurückweisen

    Wenn Sie eine Nachricht stillschweigend verwerfen wollen, erstellen oder bearbeiten Sie die Datei data/conf/rspamd/override.d/worker-proxy.custom.inc und fügen Sie den folgenden Inhalt hinzu:

    -
    discard_on_reject = true;
    -
    +

    discard_on_reject = true;

    Starten Sie Rspamd neu:

    -
    docker-compose restart rspamd-mailcow
    -
    +

    bash +docker-compose restart rspamd-mailcow

    Lösche alle Ratelimit-Schlüssel

    Wenn Sie das UI nicht verwenden wollen und stattdessen alle Schlüssel in der Redis-Datenbank löschen wollen, können Sie redis-cli für diese Aufgabe verwenden:

    -
    docker-compose exec redis-mailcow sh
    -# Unlink (verfügbar in Redis >=4.) löscht im Hintergrund
    -redis-cli --scan --pattern RL* | xargs redis-cli unlink
    -
    +

    ``` +docker-compose exec redis-mailcow sh

    +

    Unlink (verfügbar in Redis >=4.) löscht im Hintergrund

    +

    redis-cli --scan --pattern RL* | xargs redis-cli unlink +```

    Starten Sie Rspamd neu:

    -
    docker-compose exec redis-mailcow sh
    -
    +

    bash +docker-compose exec redis-mailcow sh

    Erneutes Senden von Quarantäne-Benachrichtigungen auslösen

    Sollte nur zur Fehlersuche verwendet werden!

    -
    docker-compose exec dovecot-mailcow bash
    -mysql -umailcow -p$DBPASS mailcow -e "update quarantine set notified = 0;"
    +

    docker-compose exec dovecot-mailcow bash +mysql -umailcow -p$DBPASS mailcow -e "update quarantine set notified = 0;" redis-cli -h redis DEL Q_LAST_NOTIFIED -quarantine_notify.py -

    +quarantine_notify.py

    Speicherung der Historie erhöhen

    Standardmäßig speichert Rspamd 1000 Elemente in der Historie.

    Die Historie wird komprimiert gespeichert.

    Es wird empfohlen, hier keinen unverhältnismäßig hohen Wert zu verwenden, probieren Sie etwas in der Größenordnung von 5000 oder 10000 und sehen Sie, wie Ihr Server damit umgeht:

    Bearbeiten Sie data/conf/rspamd/local.d/history_redis.conf:

    -
    nrows = 1000; # Ändern Sie diesen Wert
    -
    +

    nrows = 1000; # Ändern Sie diesen Wert

    Starten Sie anschließend Rspamd neu: docker-compose restart rspamd-mailcow


    @@ -2800,7 +2978,7 @@ quarantine_notify.py - + diff --git a/de/manual-guides/SOGo/u_e-sogo/index.html b/de/manual-guides/SOGo/u_e-sogo/index.html index 83699f904..77abe9b82 100644 --- a/de/manual-guides/SOGo/u_e-sogo/index.html +++ b/de/manual-guides/SOGo/u_e-sogo/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2519,53 +2519,51 @@ Nachdem Sie data/conf/sogo/custom-theme.js modifiziert und Änderun
  • öffnen Sie die Entwicklerkonsole des Browsers, normalerweise ist die Tastenkombination F12
  • nur wenn Sie Firefox benutzen: schreiben Sie mit der Hand in die Entwicklerkonsole allow pasting und drücken Sie Enter
  • fügen Sie den Java-Script-Schnipsel in die Entwicklungskonsole ein: -
    copy([].slice.call(document.styleSheets)
    +copy([].slice.call(document.styleSheets)
       .map(e => e.ownerNode)
    -  .filter(e => e.hasAttribute('md-theme-style'))
    +  .filter(e => e.hasAttribute('md-theme-style'))
       .map(e => e.textInhalt)
    -  .join('\n')
    -)
    -
  • + .join('\n') +)
  • Öffnen Sie den Texteditor und fügen Sie die Daten aus der Zwischenablage ein (Strg+V), Sie sollten ein minimiertes CSS erhalten, speichern Sie es
  • kopieren Sie die CSS-Datei auf den Mailcow-Server data/conf/sogo/custom-theme.css
  • editiere data/conf/sogo/sogo.conf und setze SOGoUIxDebugEnabled = NO;
  • Anhängen/Erstellen von docker-compose.override.yml mit: -
    Version: '2.1'
    -
    -Dienste:
    +```
    +Version: '2.1'
  • + +

    Dienste: sogo-mailcow: volumes: - ./data/conf/sogo/custom-theme.css:/usr/lib/GNUstep/SOGo/WebServerResources/css/theme-default.css:z -

    -
  • führen Sie docker-compose up -d aus
  • -
  • Ausführen von docker-compose restart memcached-mailcow
  • - +`` +11. führen Siedocker-compose up -daus +12. Ausführen vondocker-compose restart memcached-mailcow`

    Zurücksetzen auf das SOGo Standardthema

    1. checken Sie data/conf/sogo/custom-theme.js aus, indem Sie git fetch ; git checkout origin/master data/conf/sogo/custom-theme.js data/conf/sogo/custom-theme.js ausführen
    2. Suchen Sie in data/conf/sogo/custom-theme.js: -
      // Neue Paletten auf das Standardthema anwenden, einige Farbtöne neu zuordnen
      -    $mdThemingProvider.theme('default')
      -      .primaryPalette('green-cow', {
      -        'default': '400', // Hintergrundfarbe der oberen Symbolleisten
      -        hue-1': '400',
      -        'hue-2': '600', // Hintergrundfarbe der Seitenleiste
      -        'hue-3': 'A700'
      +// Neue Paletten auf das Standardthema anwenden, einige Farbtöne neu zuordnen
      +    $mdThemingProvider.theme('default')
      +      .primaryPalette('green-cow', {
      +        'default': '400', // Hintergrundfarbe der oberen Symbolleisten
      +        hue-1': '400',
      +        'hue-2': '600', // Hintergrundfarbe der Seitenleiste
      +        'hue-3': 'A700'
             })
      -      .accentPalette('green', {
      -        'default': '600', // Hintergrundfarbe der Fab-Schaltflächen und des Anmeldebildschirms
      -        hue-1': '300', // Hintergrundfarbe der Symbolleiste der mittleren Liste
      -        hue-2': '300', // Hervorhebungsfarbe für ausgewählte Nachrichten und den aktuellen Tageskalender
      -        hue-3': 'A700'
      +      .accentPalette('green', {
      +        'default': '600', // Hintergrundfarbe der Fab-Schaltflächen und des Anmeldebildschirms
      +        hue-1': '300', // Hintergrundfarbe der Symbolleiste der mittleren Liste
      +        hue-2': '300', // Hervorhebungsfarbe für ausgewählte Nachrichten und den aktuellen Tageskalender
      +        hue-3': 'A700'
             })
      -      .backgroundPalette('frost-grey');
      -
      + .backgroundPalette('frost-grey'); und ersetzen Sie es durch: -
          $mdThemingProvider.theme('default');
      -
    3. +$mdThemingProvider.theme('default');
    4. Entfernen Sie aus docker-compose.override.yml Volume Mount in sogo-mailcow: -
      - ./data/conf/sogo/custom-theme.css:/usr/lib/GNUstep/SOGo/WebServerResources/css/theme-default.css:z
      -
    5. +``` +
    6. ./data/conf/sogo/custom-theme.css:/usr/lib/GNUstep/SOGo/WebServerResources/css/theme-default.css:z +```
    7. führen Sie docker-compose up -d aus
    8. Starten Sie docker-compose restart memcached-mailcow.
    @@ -2581,16 +2579,14 @@ Nachdem Sie diese Datei ersetzt haben, müssen Sie SOGo und Memcached Container

    Domains sind normalerweise voneinander isoliert.

    Sie können das ändern, indem Sie data/conf/sogo/sogo.conf modifizieren:

    Suche... -

       // SOGoDomainsVisibility = (
    +// SOGoDomainsVisibility = (
         // (domain1.tld, domain5.tld),
         // (domain3.tld, domain2.tld)
    -    // );
    -
    + // ); ...und ersetzen Sie diese durch - zum Beispiel:

    -
        SOGoDomainsVisibility = (
    +

    SOGoDomainsVisibility = ( (beispiel.org, beispiel.com, beispiel.net) - ); -

    + );

    SOGo neu starten: docker-compose restart sogo-mailcow

    Deaktivieren Sie die Passwortänderung

    Bearbeiten Sie data/conf/sogo/sogo.conf und ändern Sie SOGoPasswordChangeEnabled auf NO. Bitte fügen Sie keinen neuen Parameter hinzu.

    @@ -2716,7 +2712,7 @@ Nachdem Sie diese Datei ersetzt haben, müssen Sie SOGo und Memcached Container - + diff --git a/de/manual-guides/Unbound/u_e-unbound-fwd/index.html b/de/manual-guides/Unbound/u_e-unbound-fwd/index.html index 5565d61e4..9d8b4a446 100644 --- a/de/manual-guides/Unbound/u_e-unbound-fwd/index.html +++ b/de/manual-guides/Unbound/u_e-unbound-fwd/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2444,18 +2444,15 @@ Wichtig: Nur DNSSEC-validierende DNS-Dienste werden funktionieren.

    Methode A, Unbound

    Bearbeiten Sie data/conf/unbound/unbound.conf und fügen Sie die folgenden Parameter hinzu:

    -
    forward-zone:
    -  name: "."
    +

    forward-zone: + name: "." forward-addr: 8.8.8.8 # VERWENDEN SIE KEINE ÖFFENTLICHEN DNS-SERVER - NUR EIN BEISPIEL - forward-addr: 8.8.4.4 # VERWENDET KEINE ÖFFENTLICHEN DNS-SERVER - NUR EIN BEISPIEL -

    + forward-addr: 8.8.4.4 # VERWENDET KEINE ÖFFENTLICHEN DNS-SERVER - NUR EIN BEISPIEL

    Unbound neu starten:

    -
    docker-compose restart unbound-mailcow
    -
    +

    docker-compose restart unbound-mailcow

    Methode B, Überschreiben der Datei

    -
    cd /opt/mailcow-dockerized
    -cp helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml .
    -
    +

    cd /opt/mailcow-dockerized +cp helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml .

    Bearbeiten Sie docker-compose.override.yml und passen Sie die IP an.

    Führen Sie docker-compose down ; docker-compose up -d aus.

    @@ -2577,7 +2574,7 @@ cp helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.over - + diff --git a/de/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html b/de/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html index 8ab270ab1..12c239f3e 100644 --- a/de/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html +++ b/de/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2677,7 +2677,7 @@

    Watchdog verwendet Standardwerte für alle in docker-compose.yml definierten Thresholde.

    Die Standardwerte sind für die meisten Konfigurationen geeignet. Beispiel: -

    - NGINX_THRESHOLD=${NGINX_THRESHOLD:-5}
    +- NGINX_THRESHOLD=${NGINX_THRESHOLD:-5}
     - UNBOUND_THRESHOLD=${UNBOUND_THRESHOLD:-5}
     - REDIS_THRESHOLD=${REDIS_THRESHOLD:-5}
     - MYSQL_THRESHOLD=${MYSQL_THRESHOLD:-5}
    @@ -2694,8 +2694,7 @@ Beispiel:
     - RSPAMD_THRESHOLD=${RSPAMD_THRESHOLD:-5}
     - OLEFY_THRESHOLD=${OLEFY_THRESHOLD:-5}
     - MAILQ_THRESHOLD=${MAILQ_THRESHOLD:-20}
    -- MAILQ_CRIT=${MAILQ_CRIT:-30}
    -

    +- MAILQ_CRIT=${MAILQ_CRIT:-30}

    Um sie anzupassen, fügen Sie einfach die notwendigen Threshold Variablen (z.B. MAILQ_THRESHOLD=10) zu mailcow.conf hinzu und führen docker-compose up -d aus.

    Threshold Beschreibungen

    NGINX_THRESHOLD

    @@ -2851,7 +2850,7 @@ Beispiel: - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html index c587b1ff3..e57710357 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2502,7 +2502,7 @@ - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html index ca54e4447..eba0c7160 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2518,7 +2518,7 @@ - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html index f9d5d9421..eb2ebba3f 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2496,7 +2496,7 @@ - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html index 8ad35c8e4..11f722d11 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2581,7 +2581,7 @@ - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html index bfe121ec5..0eea98e86 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2578,7 +2578,7 @@ Sollte das der Fall sein empfiehlt es sich mit einem Klick auf Zurücksetz - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html index c5c4b7597..7b3308bbf 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2506,7 +2506,7 @@ - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html index 864373e68..7f6a7412a 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2497,7 +2497,7 @@ - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html index 1fffe89eb..fed97b109 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2501,7 +2501,7 @@ Für eine domainweite Black- und Whitelist lesen Sie bitte unsere Anleitung zu < - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html index d6c674bd2..fd7762236 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2431,20 +2431,19 @@

    1. Diese Nachricht in einen Unterordner "facebook" verschieben (wird in Kleinbuchstaben erstellt, falls nicht vorhanden)

    2. Den Tag dem Betreff voranstellen: "[facebook] Betreff"

    Bitte beachten Sie: Großgeschriebene Tags werden in Kleinbuchstaben umgewandelt, mit Ausnahme des ersten Buchstabens. Wenn Sie den Tag so lassen wollen, wie er ist, wenden Sie bitte den folgenden Diff an und starten Sie mailcow neu: -

    diff --git a/data/conf/dovecot/global_sieve_after b/data/conf/dovecot/global_sieve_after
    +diff --git a/data/conf/dovecot/global_sieve_after b/data/conf/dovecot/global_sieve_after
     index e047136e..933c4137 100644
     --- a/data/conf/dovecot/global_sieve_after
     +++ b/data/conf/dovecot/global_sieve_after
     @@ -15,7 +15,7 @@ if allof (
    -   envelope :detail :matches "to" "*",
    -   header :contains "X-Moo-Tag" "YES"
    +   envelope :detail :matches "to" "*",
    +   header :contains "X-Moo-Tag" "YES"
        ) {
    --  set :lower :upperfirst "tag" "${1}";
    -+  set "tag" "${1}";
    -   if mailboxexists "INBOX/${1}" {
    -     fileinto "INBOX/${1}";
    -   } else {
    -

    +- set :lower :upperfirst "tag" "${1}"; ++ set "tag" "${1}"; + if mailboxexists "INBOX/${1}" { + fileinto "INBOX/${1}"; + } else {


    @@ -2564,7 +2563,7 @@ index e047136e..933c4137 100644 - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html index b19162c91..d6dc72115 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2604,7 +2604,7 @@ Um sie zu sehen, klicken Sie einfach auf das kleine Plus-Symbol auf der linken S - + diff --git a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html index ae0926625..3a2be87f6 100644 --- a/de/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html +++ b/de/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2778,7 +2778,7 @@ Diese Herstellerzertifikate werden nur zur Überprüfung der Originalhardware ve - + diff --git a/de/manual-guides/u_e-80_to_443/index.html b/de/manual-guides/u_e-80_to_443/index.html index 0bc5e68a8..35e982419 100644 --- a/de/manual-guides/u_e-80_to_443/index.html +++ b/de/manual-guides/u_e-80_to_443/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,27 +2377,24 @@

    Verwenden Sie die untenstehende Konfiguration nicht für Reverse-Proxy-Setups, bitte lesen Sie dazu unsere Reverse-Proxy-Anleitung, die einen Redirect von HTTP zu HTTPS beinhaltet.

    Öffne mailcow.conf und setze HTTP_BIND= - falls nicht bereits gesetzt.

    Erstellen Sie eine neue Datei data/conf/nginx/redirect.conf und fügen Sie die folgende Serverkonfiguration in die Datei ein:

    -
    server {
    +

    server { root /web; listen 80 default_server; listen [::]:80 default_server; include /etc/nginx/conf.d/server_name.active; - if ( $request_uri ~* "%0A|%0D" ) { return 403; } + if ( $request_uri ~* "%0A|%0D" ) { return 403; } location ^~ /.well-known/acme-challenge/ { allow all; - default_type "text/plain"; + default_type "text/plain"; } location / { return 301 https://$host$uri$is_args$args; } -} -

    +}

    Falls Sie den Parameter HTTP_BIND geändert haben, erstellen Sie den Container neu:

    -
    docker-compose up -d
    -
    +

    docker-compose up -d

    Andernfalls starten Sie Nginx neu:

    -
    docker-compose restart nginx-mailcow
    -
    +

    docker-compose restart nginx-mailcow


    @@ -2517,7 +2514,7 @@ - + diff --git a/de/manual-guides/u_e-autodiscover_config/index.html b/de/manual-guides/u_e-autodiscover_config/index.html index 25367f914..59caf7dfe 100644 --- a/de/manual-guides/u_e-autodiscover_config/index.html +++ b/de/manual-guides/u_e-autodiscover_config/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2378,45 +2378,44 @@ Denken Sie daran, dass ActiveSync NICHT mit einem Desktop-Client verwendet werden sollte.

    Öffnen/erstellen Sie data/web/inc/vars.local.inc.php und fügen Sie Ihre Änderungen in das Konfigurationsfeld ein.

    Die Änderungen werden mit "$autodiscover_config" in data/web/inc/vars.inc.php zusammengeführt):

    -
    <?php
    +

    <?php $autodiscover_config = array( - // General autodiscover service type: "activesync" or "imap" + // General autodiscover service type: "activesync" or "imap" // emClient uses autodiscover, but does not support ActiveSync. mailcow excludes emClient from ActiveSync. - 'autodiscoverType' => 'activesync', + 'autodiscoverType' => 'activesync', // If autodiscoverType => activesync, also use ActiveSync (EAS) for Outlook desktop clients (>= Outlook 2013 on Windows) // Outlook for Mac does not support ActiveSync - 'useEASforOutlook' => 'yes', - // Please don't use STARTTLS-enabled service ports in the "port" variable. + 'useEASforOutlook' => 'yes', + // Please don't use STARTTLS-enabled service ports in the "port" variable. // The autodiscover service will always point to SMTPS and IMAPS (TLS-wrapped services). - // The autoconfig service will additionally announce the STARTTLS-enabled ports, specified in the "tlsport" variable. - 'imap' => array( - 'server' => $mailcow_hostname, - 'port' => array_pop(explode(':', getenv('IMAPS_PORT'))), - 'tlsport' => array_pop(explode(':', getenv('IMAP_PORT'))), + // The autoconfig service will additionally announce the STARTTLS-enabled ports, specified in the "tlsport" variable. + 'imap' => array( + 'server' => $mailcow_hostname, + 'port' => array_pop(explode(':', getenv('IMAPS_PORT'))), + 'tlsport' => array_pop(explode(':', getenv('IMAP_PORT'))), ), - 'pop3' => array( - 'server' => $mailcow_hostname, - 'port' => array_pop(explode(':', getenv('POPS_PORT'))), - 'tlsport' => array_pop(explode(':', getenv('POP_PORT'))), + 'pop3' => array( + 'server' => $mailcow_hostname, + 'port' => array_pop(explode(':', getenv('POPS_PORT'))), + 'tlsport' => array_pop(explode(':', getenv('POP_PORT'))), ), - 'smtp' => array( - 'server' => $mailcow_hostname, - 'port' => array_pop(explode(':', getenv('SMTPS_PORT'))), - 'tlsport' => array_pop(explode(':', getenv('SUBMISSION_PORT'))), + 'smtp' => array( + 'server' => $mailcow_hostname, + 'port' => array_pop(explode(':', getenv('SMTPS_PORT'))), + 'tlsport' => array_pop(explode(':', getenv('SUBMISSION_PORT'))), ), - 'activesync' => array( - 'url' => 'https://'.$mailcow_hostname.($https_port == 443 ? '' : ':'.$https_port).'/Microsoft-Server-ActiveSync', + 'activesync' => array( + 'url' => 'https://'.$mailcow_hostname.($https_port == 443 ? '' : ':'.$https_port).'/Microsoft-Server-ActiveSync', ), - 'caldav' => array( - 'server' => $mailcow_hostname, - 'port' => $https_port, + 'caldav' => array( + 'server' => $mailcow_hostname, + 'port' => $https_port, ), - 'carddav' => array( - 'server' => $mailcow_hostname, - 'port' => $https_port, + 'carddav' => array( + 'server' => $mailcow_hostname, + 'port' => $https_port, ), -); -

    +);

    Um immer IMAP und SMTP anstelle von EAS zu verwenden, setzen Sie 'autodiscoverType' => 'imap'.

    Deaktivieren Sie ActiveSync für Outlook-Desktop-Clients, indem Sie "useEASforOutlook" auf "no" setzen.

    @@ -2538,7 +2537,7 @@ $autodiscover_config = array( - + diff --git a/de/manual-guides/u_e-reeanble-weak-protocols/index.html b/de/manual-guides/u_e-reeanble-weak-protocols/index.html index 5a3f6c5d1..c3968220d 100644 --- a/de/manual-guides/u_e-reeanble-weak-protocols/index.html +++ b/de/manual-guides/u_e-reeanble-weak-protocols/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,15 +2377,12 @@

    Unauthentifizierte Mails über SMTP an Port 25/tcp akzeptieren weiterhin >= TLS 1.0 . Es ist besser, eine schwache Verschlüsselung zu akzeptieren als gar keine.

    Wie kann man schwache Protokolle wieder aktivieren?

    Bearbeiten Sie data/conf/postfix/extra.cf:

    -
    submission_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
    -smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
    -
    +

    submission_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 +smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3

    Bearbeiten Sie data/conf/dovecot/extra.conf:

    -
    ssl_min_protocol = TLSv1
    -
    +

    ssl_min_protocol = TLSv1

    Starten Sie die betroffenen Dienste neu:

    -
    docker-compose restart postfix-mailcow dovecot-mailcow
    -
    +

    docker-compose restart postfix-mailcow dovecot-mailcow

    Tipp: Sie können TLS 1.2 in Windows 7 aktivieren.


    @@ -2506,7 +2503,7 @@ smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 - + diff --git a/de/manual-guides/u_e-update-hooks/index.html b/de/manual-guides/u_e-update-hooks/index.html index b7386a6aa..fec7012c4 100644 --- a/de/manual-guides/u_e-update-hooks/index.html +++ b/de/manual-guides/u_e-update-hooks/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2500,7 +2500,7 @@ - + diff --git a/de/manual-guides/u_e-why_unbound/index.html b/de/manual-guides/u_e-why_unbound/index.html index 59f5dec45..fe12d8c9f 100644 --- a/de/manual-guides/u_e-why_unbound/index.html +++ b/de/manual-guides/u_e-why_unbound/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2497,7 +2497,7 @@ Wenn Sie einen öffentlichen Resolver wie Google 4x8, OpenDNS oder einen anderen - + diff --git a/de/models/model-acl/index.html b/de/models/model-acl/index.html index 94caabc73..f0c5e4d01 100644 --- a/de/models/model-acl/index.html +++ b/de/models/model-acl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2511,7 +2511,7 @@ - + diff --git a/de/models/model-passwd/index.html b/de/models/model-passwd/index.html index 0e8e8837d..098f0163a 100644 --- a/de/models/model-passwd/index.html +++ b/de/models/model-passwd/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2599,7 +2599,7 @@ Wenn SOGo deaktiviert ist, können alle unten aufgeführten Hashing-Methoden von - + diff --git a/de/models/model-sender_rcv/index.html b/de/models/model-sender_rcv/index.html index 27e79b1e7..8d5c747df 100644 --- a/de/models/model-sender_rcv/index.html +++ b/de/models/model-sender_rcv/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2573,7 +2573,7 @@ Ihnen den Zugang wie oben beschrieben gewähren.

    - + diff --git a/de/post_installation/firststeps-disable_ipv6/index.html b/de/post_installation/firststeps-disable_ipv6/index.html index a7777ea87..f6d3cac33 100644 --- a/de/post_installation/firststeps-disable_ipv6/index.html +++ b/de/post_installation/firststeps-disable_ipv6/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,8 +2380,6 @@ -

    IPv6 deaktivieren

    -

    Dies wird NUR empfohlen, wenn Sie kein IPv6-fähiges Netzwerk auf Ihrem Host haben!

    Wenn Sie es wirklich brauchen, können Sie die Verwendung von IPv6 in der Compose-Datei deaktivieren. Zusätzlich können Sie auch den Start des Containers "ipv6nat-mailcow" deaktivieren, da er nicht benötigt wird, wenn Sie IPv6 nicht verwenden.

    @@ -2381,49 +2388,45 @@ zu erstellen und Ihre Änderungen am Dienst dort zu implementieren. Leider schei

    Um IPv6 im mailcow-Netzwerk zu deaktivieren, öffnen Sie docker-compose.yml mit Ihrem bevorzugten Texteditor und suchen Sie nach dem Netzwerk-Abschnitt (er befindet sich am Ende der Datei).

    1. Ändern Sie docker-compose.yml

    Ändern Sie enable_ipv6: true in enable_ipv6: false:

    -
    networks:
    +

    networks: mailcow-network: [...] enable_ipv6: true # <<< auf false setzen - [...] -

    + [...]

    2. ipv6nat-mailcow deaktivieren

    Um den ipv6nat-mailcow Container ebenfalls zu deaktivieren, gehen Sie in Ihr mailcow Verzeichnis und erstellen Sie eine neue Datei namens "docker-compose.override.yml":

    HINWEIS: Wenn Sie bereits eine Override-Datei haben, erstellen Sie diese natürlich nicht neu, sondern fügen Sie die untenstehenden Zeilen entsprechend in Ihre bestehende Datei ein!

    -
    # cd /opt/mailcow-dockerized
    -# touch docker-compose.override.yml
    -
    +

    ```

    +

    cd /opt/mailcow-dockerized

    +

    touch docker-compose.override.yml

    +

    ```

    Öffnen Sie die Datei in Ihrem bevorzugten Texteditor und tragen Sie folgendes ein:

    -
    version: '2.1'
    -services:
    -
    -    ipv6nat-mailcow:
    -      image: bash:latest
    -      restart: "no"
    -      entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]
    -
    +

    ``` +version: '2.1' +services:

    +
    ipv6nat-mailcow:
    +  image: bash:latest
    +  restart: "no"
    +  entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]
    +
    +

    ```

    Damit diese Änderungen wirksam werden, müssen Sie den Stack vollständig stoppen und dann neu starten, damit Container und Netzwerke neu erstellt werden:

    -
    docker-compose down
    -docker-compose up -d
    -
    +

    docker-compose down +docker-compose up -d

    3. Deaktivieren Sie IPv6 in unbound-mailcow

    Bearbeiten Sie data/conf/unbound/unbound.conf und setzen Sie do-ip6 auf "no":

    -
    Server:
    +

    Server: [...] do-ip6: no - [...] -

    + [...]

    unbound neu starten:

    -
    docker-compose restart unbound-mailcow
    -
    +

    docker-compose restart unbound-mailcow

    4. Deaktivieren Sie IPv6 in postfix-mailcow

    Erstellen Sie data/conf/postfix/extra.cf und setzen Sie smtp_address_preference auf ipv4:

    -
    smtp_address_preference = ipv4
    -inet_protocols = ipv4
    -
    +

    smtp_address_preference = ipv4 +inet_protocols = ipv4

    Starten Sie Postfix neu:

    -
    docker-compose restart postfix-mailcow
    -
    +

    docker-compose restart postfix-mailcow


    @@ -2543,7 +2546,7 @@ inet_protocols = ipv4 - + diff --git a/de/post_installation/firststeps-dmarc_reporting/index.html b/de/post_installation/firststeps-dmarc_reporting/index.html index aeade55c8..6f10b96f4 100644 --- a/de/post_installation/firststeps-dmarc_reporting/index.html +++ b/de/post_installation/firststeps-dmarc_reporting/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2501,44 +2501,42 @@

    Aktivieren Sie DMARC-Berichterstattung

    Erstellen Sie die Datei data/conf/rspamd/local.d/dmarc.conf und setzen Sie den folgenden Inhalt:

    -
    reporting {
    +

    reporting { enabled = true; - email = 'noreply-dmarc@example.com'; - domain = 'example.com'; - org_name = 'Example'; - helo = 'rspamd'; - smtp = 'postfix'; + email = 'noreply-dmarc@example.com'; + domain = 'example.com'; + org_name = 'Example'; + helo = 'rspamd'; + smtp = 'postfix'; smtp_port = 25; - from_name = 'Example DMARC Report'; - msgid_from = 'rspamd.mail.example.com'; + from_name = 'Example DMARC Report'; + msgid_from = 'rspamd.mail.example.com'; max_entries = 2k; keys_expire = 2d; -} -

    +}

    Erstellen oder ändern Sie docker-compose.override.yml im mailcow-dockerized Basisverzeichnis:

    -
    version: '2.1'
    -
    -services:
    +

    ``` +version: '2.1'

    +

    services: rspamd-mailcow: environment: - MASTER=${MASTER:-y} labels: - ofelia.enabled: "true" - ofelia.job-exec.rspamd_dmarc_reporting.schedule: "@every 24h" - ofelia.job-exec.rspamd_dmarc_reporting.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/bin/rspamadm dmarc_report > /var/lib/rspamd/dmarc_reports_last_log 2>&1 || exit 0\"" + ofelia.enabled: "true" + ofelia.job-exec.rspamd_dmarc_reporting.schedule: "@every 24h" + ofelia.job-exec.rspamd_dmarc_reporting.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/bin/rspamadm dmarc_report > /var/lib/rspamd/dmarc_reports_last_log 2>&1 || exit 0\"" ofelia-mailcow: depends_on: - rspamd-mailcow -

    +```

    Starte docker-compose up -d

    Senden Sie eine Kopie der Berichte an sich selbst

    Um eine versteckte Kopie der von Rspamd erzeugten Berichte zu erhalten, können Sie eine bcc_addrs Liste im reporting Konfigurationsabschnitt von data/conf/rspamd/local.d/dmarc.conf setzen:

    -
    reporting {
    +

    reporting { enabled = true; - email = 'noreply-dmarc@example.com'; - bcc_addrs = ["noreply-dmarc@example.com", "parsedmarc@example.com"]; -[...] -

    + email = 'noreply-dmarc@example.com'; + bcc_addrs = ["noreply-dmarc@example.com", "parsedmarc@example.com"]; +[...]

    Rspamd lädt Änderungen in Echtzeit, so dass Sie den Container zu diesem Zeitpunkt nicht neu starten müssen.

    Dies kann nützlich sein, wenn Sie...

      @@ -2547,21 +2545,16 @@ services:

    Fehlersuche

    Prüfen Sie, wann der Berichtsplan zuletzt ausgeführt wurde:

    -
    docker-compose exec rspamd-mailcow date -r /var/lib/rspamd/dmarc_reports_last_log
    -
    +

    docker-compose exec rspamd-mailcow date -r /var/lib/rspamd/dmarc_reports_last_log

    Sehen Sie sich die letzte Berichtsausgabe an:

    -
    docker-compose exec rspamd-mailcow cat /var/lib/rspamd/dmarc_reports_last_log
    -
    +

    docker-compose exec rspamd-mailcow cat /var/lib/rspamd/dmarc_reports_last_log

    Manuelles Auslösen eines DMARC-Berichts:

    -
    docker-compose exec rspamd-mailcow rspamadm dmarc_report
    -
    +

    docker-compose exec rspamd-mailcow rspamadm dmarc_report

    Bestätigen Sie, dass Rspamd Daten in Redis aufgezeichnet hat: Ändern Sie 20220428 in ein anderes interessantes Datum zum schauen.

    -
    docker-compose exec redis-mailcow redis-cli SMEMBERS "dmarc_idx;20220428"
    -
    +

    docker-compose exec redis-mailcow redis-cli SMEMBERS "dmarc_idx;20220428"

    Nehmen Sie eine der Zeilen aus der Ausgabe, die Sie interessiert, und fordern Sie sie an, z. B.:

    -
    docker-compose exec redis-mailcow redis-cli ZRANGE "dmarc_rpt;microsoft.com;mailto:d@rua.agari.com;20220428" 0 49
    -
    +

    docker-compose exec redis-mailcow redis-cli ZRANGE "dmarc_rpt;microsoft.com;mailto:d@rua.agari.com;20220428" 0 49

    Ändern Sie die Häufigkeit der DMARC-Berichte

    Im obigen Beispiel werden die Berichte einmal alle 24 Stunden gesendet.

    Der Olefia-Zeitplan hat die gleiche Implementierung wie cron in Go, die unterstützte Syntax ist beschrieben in cron Documentation

    @@ -2709,7 +2702,7 @@ services: - + diff --git a/de/post_installation/firststeps-ip_bindings/index.html b/de/post_installation/firststeps-ip_bindings/index.html index c5d0c3c32..6e6f7a035 100644 --- a/de/post_installation/firststeps-ip_bindings/index.html +++ b/de/post_installation/firststeps-ip_bindings/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -530,10 +530,65 @@
  • + + Aus technischen Gründen unterscheiden sich die http-Bindungen ein wenig von anderen Service-Bindungen. + + +
  • + +
  • + + Sie werden die folgenden Variablen finden, getrennt durch eine Bindungsadresse und deren Port: + + +
  • + +
  • + + Beispiel: HTTP_BIND=1.2.3.4 + + +
  • + +
  • + + Andere Dienste werden nach folgendem Format gebunden: + + +
  • + +
  • + + SMTP_PORT=1.2.3.4:25 bindet SMTP an die IP 1.2.3.4 auf Port 25 + + +
  • + +
  • + + Wichtig! Durch die Angabe einer IPv4-Adresse werden alle IPv6-Bindungen seit Docker 20.x übersprungen. + + +
  • + +
  • + + doveadm, SQL sowie Solr sind nur an lokale Ports gebunden, bitte ändern Sie das nicht, es sei denn, Sie wissen, was Sie tun. + + + +
  • @@ -2410,10 +2465,65 @@
  • + + Aus technischen Gründen unterscheiden sich die http-Bindungen ein wenig von anderen Service-Bindungen. + + +
  • + +
  • + + Sie werden die folgenden Variablen finden, getrennt durch eine Bindungsadresse und deren Port: + + +
  • + +
  • + + Beispiel: HTTP_BIND=1.2.3.4 + + +
  • + +
  • + + Andere Dienste werden nach folgendem Format gebunden: + + +
  • + +
  • + + SMTP_PORT=1.2.3.4:25 bindet SMTP an die IP 1.2.3.4 auf Port 25 + + +
  • + +
  • + + Wichtig! Durch die Angabe einer IPv4-Adresse werden alle IPv6-Bindungen seit Docker 20.x übersprungen. + + +
  • + +
  • + + doveadm, SQL sowie Solr sind nur an lokale Ports gebunden, bitte ändern Sie das nicht, es sei denn, Sie wissen, was Sie tun. + + + +
  • @@ -2434,29 +2544,25 @@ -

    IP-Verbindungen

    -

    Warning

    Das Ändern der Bindung hat keinen Einfluss auf Source-NAT. Siehe SNAT für die erforderlichen Schritte.

    IPv4-Binding

    Um eine oder mehrere IPv4-Bind(ings) anzupassen, öffne mailcow.conf und editiere eine, mehrere oder alle Variablen nach deinen Bedürfnissen:

    -
    # Aus technischen Gründen unterscheiden sich die http-Bindungen ein wenig von anderen Service-Bindungen.
    -# Sie werden die folgenden Variablen finden, getrennt durch eine Bindungsadresse und deren Port:
    -# Beispiel: HTTP_BIND=1.2.3.4
    -
    -HTTP_PORT=80
    +

    ```

    +

    Aus technischen Gründen unterscheiden sich die http-Bindungen ein wenig von anderen Service-Bindungen.

    +

    Sie werden die folgenden Variablen finden, getrennt durch eine Bindungsadresse und deren Port:

    +

    Beispiel: HTTP_BIND=1.2.3.4

    +

    HTTP_PORT=80 HTTP_BIND= HTTPS_PORT=443 -HTTPS_BIND= - -# Andere Dienste werden nach folgendem Format gebunden: -# SMTP_PORT=1.2.3.4:25 bindet SMTP an die IP 1.2.3.4 auf Port 25 -# Wichtig! Durch die Angabe einer IPv4-Adresse werden alle IPv6-Bindungen seit Docker 20.x übersprungen. -# doveadm, SQL sowie Solr sind nur an lokale Ports gebunden, bitte ändern Sie das nicht, es sei denn, Sie wissen, was Sie tun. - -SMTP_PORT=25 +HTTPS_BIND=

    +

    Andere Dienste werden nach folgendem Format gebunden:

    +

    SMTP_PORT=1.2.3.4:25 bindet SMTP an die IP 1.2.3.4 auf Port 25

    +

    Wichtig! Durch die Angabe einer IPv4-Adresse werden alle IPv6-Bindungen seit Docker 20.x übersprungen.

    +

    doveadm, SQL sowie Solr sind nur an lokale Ports gebunden, bitte ändern Sie das nicht, es sei denn, Sie wissen, was Sie tun.

    +

    SMTP_PORT=25 SMTPS_PORT=465 SUBMISSION_PORT=587 IMAP_PORT=143 @@ -2467,35 +2573,36 @@ SIEVE_PORT=4190 DOVEADM_PORT=127.0.0.1:19991 SQL_PORT=127.0.0.1:13306 SOLR_PORT=127.0.0.1:18983 -

    +```

    Um Ihre Änderungen zu übernehmen, führen Sie docker-compose down gefolgt von docker-compose up -d aus.

    IPv6-Binding

    Das Ändern von IPv6-Bindings ist anders als bei IPv4. Auch dies hat einen technischen Hintergrund.

    Eine docker-compose.override.yml Datei wird verwendet, anstatt die docker-compose.yml Datei direkt zu bearbeiten. Dies geschieht, um die Aktualisierbarkeit zu erhalten, da die Datei docker-compose.yml regelmäßig aktualisiert wird und Ihre Änderungen höchstwahrscheinlich überschrieben werden.

    Bearbeiten Sie die Datei "docker-compose.override.yml" und erstellen Sie sie mit dem folgenden Inhalt. Ihr Inhalt wird mit der produktiven Datei "docker-compose.yml" zusammengeführt.

    Es wird eine imaginäre IPv6 2a00:dead:beef::abc angegeben. Das erste Suffix :PORT1 definiert den externen Port, während das zweite Suffix :PORT2 zu dem entsprechenden Port innerhalb des Containers führt und nicht verändert werden darf.

    -
    version: '2.1'
    -services:
    +

    ``` +version: '2.1' +services:

    +
    dovecot-mailcow:
    +  ports:
    +    - '2a00:dead:beef::abc:143:143'
    +    - '2a00:dead:beef::abc:993:993'
    +    - '2a00:dead:beef::abc:110:110'
    +    - '2a00:dead:beef::abc:995:995'
    +    - '2a00:dead:beef::abc:4190:4190'
     
    -    dovecot-mailcow:
    -      ports:
    -        - '2a00:dead:beef::abc:143:143'
    -        - '2a00:dead:beef::abc:993:993'
    -        - '2a00:dead:beef::abc:110:110'
    -        - '2a00:dead:beef::abc:995:995'
    -        - '2a00:dead:beef::abc:4190:4190'
    +postfix-mailcow:
    +  ports:
    +    - '2a00:dead:beef::abc:25:25'
    +    - '2a00:dead:beef::abc:465:465'
    +    - '2a00:dead:beef::abc:587:587'
     
    -    postfix-mailcow:
    -      ports:
    -        - '2a00:dead:beef::abc:25:25'
    -        - '2a00:dead:beef::abc:465:465'
    -        - '2a00:dead:beef::abc:587:587'
    -
    -    nginx-mailcow:
    -      ports:
    -        - '2a00:dead:beef::abc:80:80'
    -        - '2a00:dead:beef::abc:443:443'
    -
    +nginx-mailcow: + ports: + - '2a00:dead:beef::abc:80:80' + - '2a00:dead:beef::abc:443:443' + +

    ```

    Um Ihre Änderungen zu übernehmen, führen Sie docker-compose down gefolgt von docker-compose up -d aus.


    @@ -2616,7 +2723,7 @@ services: - + diff --git a/de/post_installation/firststeps-local_mta/index.html b/de/post_installation/firststeps-local_mta/index.html index df00ef31a..09816692e 100644 --- a/de/post_installation/firststeps-local_mta/index.html +++ b/de/post_installation/firststeps-local_mta/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,19 +2380,17 @@ -

    Lokaler MTA auf Docker-Host

    -

    Die einfachste Möglichkeit wäre, den Listener an Port 25/tcp zu deaktivieren.

    Postfix-Benutzer deaktivieren den Listener, indem sie die folgende Zeile (beginnend mit smtp oder 25) in /etc/postfix/master.cf auskommentieren: -

    #smtp      inet  n       -       -       -       -       smtpd
    -

    +```

    +

    smtp inet n - - - - smtpd

    +

    ```

    Außerdem, um über eine Dockerized mailcow weiterzuleiten, sollten Sie 172.22.1.1 als Relayhost hinzufügen und das Docker-Interface aus "inet_interfaces" entfernen:

    -
    postconf -e 'relayhost = 172.22.1.1'
    -postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128"
    -postconf -e "inet_interfaces = loopback-only"
    -postconf -e "relay_transport = relay"
    -postconf -e "default_transport = smtp"
    -
    +

    postconf -e 'relayhost = 172.22.1.1' +postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128" +postconf -e "inet_interfaces = loopback-only" +postconf -e "relay_transport = relay" +postconf -e "default_transport = smtp"

    Jetzt ist es wichtig, dass Sie nicht denselben FQDN in myhostname haben, den Sie für Ihre mailcow verwenden. Prüfen Sie Ihre lokale (nicht-Docker) Postfix' main.cf auf myhostname und setzen Sie ihn auf etwas anderes, zum Beispiel local.my.fqdn.tld.

    "172.22.1.1" ist das von mailcow erstellte Netzwerk-Gateway in Docker. Das Relaying über diese Schnittstelle ist notwendig (anstatt - zum Beispiel - direkt über ${MAILCOW_HOSTNAME}), um über ein bekanntes internes Netzwerk weiterzuleiten.

    @@ -2507,7 +2514,7 @@ Das Relaying über diese Schnittstelle ist notwendig (anstatt - zum Beispiel - d - + diff --git a/de/post_installation/firststeps-logging/index.html b/de/post_installation/firststeps-logging/index.html index 15f0d8a92..7298c2155 100644 --- a/de/post_installation/firststeps-logging/index.html +++ b/de/post_installation/firststeps-logging/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -572,6 +572,33 @@ + + + + + +
  • + + Nur für Rsyslog: + + +
  • + +
  • + + Um die local3-Eingabe nach /var/log/mailcow.log zu verschieben und die Verarbeitung zu beenden, erstellen Sie eine Datei "/etc/rsyslog.d/docker.conf": + + +
  • + +
  • + + Danach rsyslog neu starten. + + + + +
  • + +
  • + + Nur für Rsyslog: + + +
  • + +
  • + + Um die local3-Eingabe nach /var/log/mailcow.log zu verschieben und die Verarbeitung zu beenden, erstellen Sie eine Datei "/etc/rsyslog.d/docker.conf": + + +
  • + +
  • + + Danach rsyslog neu starten. + + +
  • + + !/bin/bash + + + +
  • @@ -2490,16 +2516,14 @@ -

    Reverse Proxy

    -

    Sie müssen die Nginx-Seite, die mit mailcow: dockerized geliefert wird, nicht ändern. mailcow: dockerized vertraut auf das Standard-Gateway IP 172.22.1.1 als Proxy.

    1. Stellen Sie sicher, dass Sie HTTP_BIND und HTTPS_BIND in mailcow.conf auf eine lokale Adresse ändern und die Ports entsprechend einstellen, zum Beispiel: -

    HTTP_BIND=127.0.0.1
    -HTTP_PORT=8080
    -HTTPS_BIND=127.0.0.1
    -HTTPS_PORT=8443
    -

    +bash +HTTP_BIND=127.0.0.1 +HTTP_PORT=8080 +HTTPS_BIND=127.0.0.1 +HTTPS_PORT=8443

    Dadurch werden auch die Bindungen innerhalb des Nginx-Containers geändert! Dies ist wichtig, wenn Sie sich entscheiden, einen Proxy innerhalb von Docker zu verwenden.

    WICHTIG: Verwenden Sie nicht Port 8081, 9081 oder 65510!

    Erzeugen Sie die betroffenen Container neu, indem Sie docker-compose up -d ausführen.

    @@ -2528,81 +2552,73 @@ Auf vielen Servern wird logrotate den Webserver sowieso täglich neu laden.

    2. Konfigurieren Sie Ihren lokalen Webserver als Reverse Proxy:

    Apache 2.4

    Erforderliche Module: -

    a2enmod rewrite proxy proxy_http headers ssl
    -

    +a2enmod rewrite proxy proxy_http headers ssl

    Let's Encrypt wird unserem Rewrite folgen, Zertifikatsanfragen in mailcow werden problemlos funktionieren.

    Die hervorgehobenen Zeilen müssen beachtet werden.

    -
    <VirtualHost *:80>
    -  ServerName ZU MAILCOW HOSTNAMEN ÄNDERN
    -  ServerAlias autodiscover.*
    -  ServerAlias autoconfig.*
    -  RewriteEngine on
    -
    -  RewriteCond %{HTTPS} off
    -  RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R=301,L]
    -
    -  ProxyPass / http://127.0.0.1:8080/
    -  ProxyPassReverse / http://127.0.0.1:8080/
    -  ProxyPreserveHost On
    -  ProxyAddHeaders On
    -  RequestHeader set X-Forwarded-Proto "http"
    -</VirtualHost>
    -<VirtualHost *:443>
    -  ServerName ZU MAILCOW HOSTNAMEN ÄNDERN
    -  ServerAlias autodiscover.*
    -  ServerAlias autoconfig.*
    -
    -  # You should proxy to a plain HTTP session to offload SSL processing
    -  ProxyPass /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync connectiontimeout=4000
    -  ProxyPassReverse /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync
    -  ProxyPass / http://127.0.0.1:8080/
    -  ProxyPassReverse / http://127.0.0.1:8080/
    -  ProxyPreserveHost On
    -  ProxyAddHeaders On
    -  RequestHeader set X-Forwarded-Proto "https"
    -
    -  SSLCertificateFile MAILCOW_ORDNER/data/assets/ssl/cert.pem
    -  SSLCertificateKeyFile MAILCOW_ORDNER/data/assets/ssl/key.pem
    -
    -  # Wenn Sie einen HTTPS-Host als Proxy verwenden möchten:
    -  #SSLProxyEngine On
    -
    -  # Wenn Sie einen Proxy für einen nicht vertrauenswürdigen HTTPS-Host einrichten wollen:
    -  #SSLProxyVerify none
    -  #SSLProxyCheckPeerCN off
    -  #SSLProxyCheckPeerName off
    -  #SSLProxyCheckPeerExpire off
    -</VirtualHost>
    -
    +

    ``` apache hl_lines="2 10 11 17 22 23 24 25 30 31" + + ServerName ZU MAILCOW HOSTNAMEN ÄNDERN + ServerAlias autodiscover.* + ServerAlias autoconfig.* + RewriteEngine on

    +

    RewriteCond %{HTTPS} off + RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R=301,L]

    +

    ProxyPass / http://127.0.0.1:8080/ + ProxyPassReverse / http://127.0.0.1:8080/ + ProxyPreserveHost On + ProxyAddHeaders On + RequestHeader set X-Forwarded-Proto "http" + + + ServerName ZU MAILCOW HOSTNAMEN ÄNDERN + ServerAlias autodiscover.* + ServerAlias autoconfig.*

    +

    # You should proxy to a plain HTTP session to offload SSL processing + ProxyPass /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync connectiontimeout=4000 + ProxyPassReverse /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync + ProxyPass / http://127.0.0.1:8080/ + ProxyPassReverse / http://127.0.0.1:8080/ + ProxyPreserveHost On + ProxyAddHeaders On + RequestHeader set X-Forwarded-Proto "https"

    +

    SSLCertificateFile MAILCOW_ORDNER/data/assets/ssl/cert.pem + SSLCertificateKeyFile MAILCOW_ORDNER/data/assets/ssl/key.pem

    +

    # Wenn Sie einen HTTPS-Host als Proxy verwenden möchten: + #SSLProxyEngine On

    +

    # Wenn Sie einen Proxy für einen nicht vertrauenswürdigen HTTPS-Host einrichten wollen: + #SSLProxyVerify none + #SSLProxyCheckPeerCN off + #SSLProxyCheckPeerName off + #SSLProxyCheckPeerExpire off + +```

    Nginx

    Let's Encrypt folgt unserem Rewrite, Zertifikatsanfragen funktionieren problemlos.

    Achten Sie auf die hervorgehobenen Zeilen.

    -
    server {
    +

    ``` hl_lines="4 10 12 13 25 39" +server { listen 80 default_server; listen [::]:80 default_server; - server_name ZU MAILCOW HOSTNAMEN ÄNDERN autodiscover.* autoconfig.*; - return 301 https://$host$request_uri; + server_name ZU MAILCOW HOSTNAMEN ÄNDERN autodiscover.* autoconfig.; + return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; - server_name ZU MAILCOW HOSTNAMEN ÄNDERN autodiscover.* autoconfig.*; - - ssl_certificate MAILCOW_PATH/data/assets/ssl/cert.pem; - ssl_certificate_key MAILCOW_PATH/data/assets/ssl/key.pem; - ssl_session_timeout 1d; + server_name ZU MAILCOW HOSTNAMEN ÄNDERN autodiscover. autoconfig.*;

    +

    ssl_certificate MAILCOW_PATH/data/assets/ssl/cert.pem; + ssl_certificate_key MAILCOW_PATH/data/assets/ssl/key.pem; + ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; - ssl_session_tickets off; - - # Siehe https://ssl-config.mozilla.org/#server=nginx für die neuesten Empfehlungen zu ssl-Einstellungen + ssl_session_tickets off;

    +

    # Siehe https://ssl-config.mozilla.org/#server=nginx für die neuesten Empfehlungen zu ssl-Einstellungen # Ein Beispiel für eine Konfiguration ist unten angegeben ssl_protocols TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5:!SHA1:!kRSA; - ssl_prefer_server_ciphers off; - - location /Microsoft-Server-ActiveSync { - proxy_pass http://127.0.0.1:8080/Microsoft-Server-ActiveSync; - proxy_set_header Host $http_host; + ssl_prefer_server_ciphers off;

    +

    location /Microsoft-Server-ActiveSync { + proxy_pass http://127.0.0.1:8080/Microsoft-Server-ActiveSync; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; @@ -2612,39 +2628,38 @@ server { proxy_buffers 64 512k; # Seit dem 2022-04 Update nötig für SOGo client_body_buffer_size 512k; client_max_body_size 0; - } - - location / { - proxy_pass http://127.0.0.1:8080/; - proxy_set_header Host $http_host; + }

    +

    location / { + proxy_pass http://127.0.0.1:8080/; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 0; # Die folgenden Proxy-Buffer müssen gesetzt werden, wenn Sie SOGo nach dem Update 2022-04 (April 2022) verwenden wollen - # Andernfalls wird ein Login wie folgt fehlschlagen: https://github.com/mailcow/mailcow-dockerized/issues/4537 + # Andernfalls wird ein Login wie folgt fehlschlagen: https://github.com/mailcow/mailcow-dockerized/issues/4537 proxy_buffer_size 128k; proxy_buffers 64 512k; proxy_busy_buffers_size 512k; } } -

    +```

    HAProxy (von der Community unterstützt)

    Warning

    Dies ist ein nicht unterstützter Community Beitrag. Sie können gerne Korrekturen bereitstellen.

    Wichtig/Fix erwünscht: Dieses Beispiel leitet nur HTTPS-Verkehr weiter und benutzt nicht den in mailcow eingebauten ACME-Client.

    -
    frontend https-in
    +

    ``` +frontend https-in bind :::443 v4v6 ssl crt mailcow.pem - default_backend mailcow - -backend mailcow + default_backend mailcow

    +

    backend mailcow option forwardfor http-request set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Proto http if !{ ssl_fc } server mailcow 127.0.0.1:8080 check -

    +```

    Traefik v2 (von der Community unterstützt)

    Warning

    @@ -2655,50 +2670,49 @@ backend mailcow

    Zuallererst werden wir den acme-mailcow-Container deaktivieren, da wir die von traefik bereitgestellten Zertifikate verwenden werden. Dazu müssen wir SKIP_LETS_ENCRYPT=y in unserer mailcow.conf setzen und docker-compose up -d ausführen, um die Änderungen zu übernehmen.

    Dann erstellen wir eine docker-compose.override.yml Datei, um die Hauptdatei docker-compose.yml zu überschreiben, die sich im Mailcow-Stammverzeichnis befindet.

    -
    version: '2.1'
    -
    -services:
    -    nginx-mailcow:
    -      networks:
    -        # Traefiks Netzwerk hinzufügen
    -        web:
    -      labels:
    -        - traefik.enable=true
    -        # Erstellt einen Router namens "moo" für den Container und richtet eine Regel ein, um den Container mit einer bestimmten Regel zu verknüpfen,
    -        # in diesem Fall eine Host-Regel mit unserer MAILCOW_HOSTNAME-Variable.
    -        - traefik.http.routers.moo.rule=Host(`${MAILCOW_HOSTNAME}`)
    -        # Aktiviert tls über den zuvor erstellten Router.
    -        - traefik.http.routers.moo.tls=true
    -        # Gibt an, welche Art von Cert-Resolver wir verwenden werden, in diesem Fall le (Lets Encrypt).
    -        - traefik.http.routers.moo.tls.certresolver=le
    -        # Erzeugt einen Dienst namens "moo" für den Container und gibt an, welchen internen Port des Containers
    -        # Traefik die eingehenden Daten weiterleiten soll.
    -        - traefik.http.services.moo.loadbalancer.server.port=${HTTP_PORT}
    -        # Gibt an, welchen Eingangspunkt (externer Port) traefik für diesen Container abhören soll.
    -        # Websecure ist Port 443, siehe die Datei traefik.toml wie oben.
    -        - traefik.http.routers.moo.entrypoints=websecure
    -        # Stellen Sie sicher, dass traefik das Web-Netzwerk verwendet, nicht das mailcowdockerized_mailcow-network
    -        - traefik.docker.network=web
    -
    -    certdumper:
    -        image: humenius/traefik-certs-dumper
    -        container_name: traefik_certdumper
    -        network_mode: none
    -        volumes:
    -          # mounten Sie den Ordner, der Traefiks `acme.json' Datei enthält
    -          # in diesem Fall wird Traefik von seinem eigenen docker-compose in ../traefik gestartet
    -          - ../traefik/data:/traefik:ro
    -          # SSL-Ordner von mailcow einhängen
    -          - ./data/assets/ssl/:/output:rw
    -        restart: always
    -        environment:
    -          # Ändern Sie dies nur, wenn Sie eine andere Domain für Mailcows Web-Frontend verwenden als in der Standard-Konfiguration
    -          - DOMAIN=${MAILCOW_HOSTNAME}
    -
    -networks:
    -  web:
    -    external: true
    -
    +

    ```yaml +version: '2.1'

    +

    services: + nginx-mailcow: + networks: + # Traefiks Netzwerk hinzufügen + web: + labels: + - traefik.enable=true + # Erstellt einen Router namens "moo" für den Container und richtet eine Regel ein, um den Container mit einer bestimmten Regel zu verknüpfen, + # in diesem Fall eine Host-Regel mit unserer MAILCOW_HOSTNAME-Variable. + - traefik.http.routers.moo.rule=Host(${MAILCOW_HOSTNAME}) + # Aktiviert tls über den zuvor erstellten Router. + - traefik.http.routers.moo.tls=true + # Gibt an, welche Art von Cert-Resolver wir verwenden werden, in diesem Fall le (Lets Encrypt). + - traefik.http.routers.moo.tls.certresolver=le + # Erzeugt einen Dienst namens "moo" für den Container und gibt an, welchen internen Port des Containers + # Traefik die eingehenden Daten weiterleiten soll. + - traefik.http.services.moo.loadbalancer.server.port=${HTTP_PORT} + # Gibt an, welchen Eingangspunkt (externer Port) traefik für diesen Container abhören soll. + # Websecure ist Port 443, siehe die Datei traefik.toml wie oben. + - traefik.http.routers.moo.entrypoints=websecure + # Stellen Sie sicher, dass traefik das Web-Netzwerk verwendet, nicht das mailcowdockerized_mailcow-network + - traefik.docker.network=web

    +
    certdumper:
    +    image: humenius/traefik-certs-dumper
    +    container_name: traefik_certdumper
    +    network_mode: none
    +    volumes:
    +      # mounten Sie den Ordner, der Traefiks `acme.json' Datei enthält
    +      # in diesem Fall wird Traefik von seinem eigenen docker-compose in ../traefik gestartet
    +      - ../traefik/data:/traefik:ro
    +      # SSL-Ordner von mailcow einhängen
    +      - ./data/assets/ssl/:/output:rw
    +    restart: always
    +    environment:
    +      # Ändern Sie dies nur, wenn Sie eine andere Domain für Mailcows Web-Frontend verwenden als in der Standard-Konfiguration
    +      - DOMAIN=${MAILCOW_HOSTNAME}
    +
    +

    networks: + web: + external: true +```

    Starten Sie die neuen Container mit docker-compose up -d.

    Da Traefik 2 ein acme v2 Format verwendet, um ALLE Lizenzen von allen Domains zu speichern, müssen wir einen Weg finden, die Zertifikate auszulagern. Zum Glück haben wir [diesen kleinen Container] (https://hub.docker.com/r/humenius/traefik-certs-dumper), der die Datei acme.json über ein Volume und eine Variable DOMAIN=example. org, und damit wird der Container die cert.pem und key.pem Dateien ausgeben, dafür lassen wir einfach den traefik-certs-dumper Container laufen, binden das /traefik Volume an den Ordner, in dem unsere acme.json gespeichert ist, binden das /output Volume an unseren mailcow data/assets/ssl/ Ordner, und setzen die DOMAIN=example.org Variable auf die Domain, von der wir die Zertifikate ausgeben wollen.

    Dieser Container überwacht die Datei acme.json auf Änderungen und generiert die Dateien cert.pem und key.pem direkt in data/assets/ssl/, wobei der Pfad mit dem /output-Pfad des Containers verbunden ist.

    @@ -2708,18 +2722,18 @@ Dazu müssen wir SKIP_LETS_ENCRYPT=y in unserer mailcow.conf<

    Optional: Post-Hook-Skript für nicht-mailcow ACME-Clients

    Die Verwendung eines lokalen Certbots (oder eines anderen ACME-Clients) erfordert den Neustart einiger Container, was Sie mit einem Post-Hook-Skript erledigen können. Stellen Sie sicher, dass Sie die Pfade entsprechend ändern: -

    #!/bin/bash
    -cp /etc/letsencrypt/live/my.domain.tld/fullchain.pem /opt/mailcow-dockerized/data/assets/ssl/cert.pem
    +```

    +

    !/bin/bash

    +

    cp /etc/letsencrypt/live/my.domain.tld/fullchain.pem /opt/mailcow-dockerized/data/assets/ssl/cert.pem cp /etc/letsencrypt/live/my.domain.tld/privkey.pem /opt/mailcow-dockerized/data/assets/ssl/key.pem postfix_c=$(docker ps -qaf name=postfix-mailcow) dovecot_c=$(docker ps -qaf name=dovecot-mailcow) nginx_c=$(docker ps -qaf name=nginx-mailcow) docker restart ${postfix_c} ${dovecot_c} ${nginx_c} -

    +```

    Hinzufügen weiterer Servernamen für mailcow UI

    Wenn Sie vorhaben, einen Servernamen zu verwenden, der nicht MAILCOW_HOSTNAME in Ihrem Reverse-Proxy ist, stellen Sie sicher, dass Sie diesen Namen zuerst in mailcow.conf über ADDITIONAL_SERVER_NAMES einpflegen. Die Namen müssen durch Kommas getrennt werden und dürfen keine Leerzeichen enthalten. Wenn Sie diesen Schritt überspringen, kann es sein, dass mailcow auf Ihren Reverse-Proxy mit einer falschen Seite antwortet.

    -
    ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld
    -
    +

    ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld

    Führen Sie docker-compose up -d zum Anwenden aus.


    @@ -2840,7 +2854,7 @@ docker restart ${postfix_c} ${dovecot_c} ${nginx_c} - + diff --git a/de/post_installation/firststeps-rspamd_ui/index.html b/de/post_installation/firststeps-rspamd_ui/index.html index 2356be8a1..dc900c44f 100644 --- a/de/post_installation/firststeps-rspamd_ui/index.html +++ b/de/post_installation/firststeps-rspamd_ui/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2500,7 +2500,7 @@ - + diff --git a/de/post_installation/firststeps-snat/index.html b/de/post_installation/firststeps-snat/index.html index 5c3ed2345..cb749b044 100644 --- a/de/post_installation/firststeps-snat/index.html +++ b/de/post_installation/firststeps-snat/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@
    @@ -564,6 +569,8 @@ + + SNAT @@ -2354,6 +2361,8 @@ + +
    @@ -2371,17 +2380,15 @@ -

    SNAT

    -

    SNAT wird verwendet, um die Quelladresse der von mailcow gesendeten Pakete zu ändern. Es kann verwendet werden, um die ausgehende IP-Adresse auf Systemen mit mehreren IP-Adressen zu ändern.

    Öffnen Sie mailcow.conf, setzen Sie einen oder beide der folgenden Parameter:

    -
    # Benutze diese IPv4 für ausgehende Verbindungen (SNAT)
    -SNAT_TO_SOURCE=1.2.3.4
    -
    -# Benutze dieses IPv6 für ausgehende Verbindungen (SNAT)
    -SNAT6_TO_SOURCE=dead:beef
    -
    +

    ```

    +

    Benutze diese IPv4 für ausgehende Verbindungen (SNAT)

    +

    SNAT_TO_SOURCE=1.2.3.4

    +

    Benutze dieses IPv6 für ausgehende Verbindungen (SNAT)

    +

    SNAT6_TO_SOURCE=dead:beef +```

    Führen Sie docker-compose up -d aus.

    Die Werte werden von netfilter-mailcow gelesen. netfilter-mailcow stellt sicher, dass die Post-Routing-Regeln auf Position 1 in der Netfilter-Tabelle stehen. Es löscht sie automatisch und legt sie neu an, wenn sie an einer anderen Position als 1 gefunden werden.

    Überprüfen Sie die Ausgabe von docker-compose logs --tail=200 netfilter-mailcow, um sicherzustellen, dass die SNAT-Einstellungen angewendet wurden.

    @@ -2504,7 +2511,7 @@ SNAT6_TO_SOURCE=dead:beef - + diff --git a/de/post_installation/firststeps-ssl/index.html b/de/post_installation/firststeps-ssl/index.html index e36e7152a..52dffa66f 100644 --- a/de/post_installation/firststeps-ssl/index.html +++ b/de/post_installation/firststeps-ssl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -502,6 +502,19 @@ + + + + + +
  • + + Prüfen Sie nun die Logs auf eine Erneuerung + + + +
  • + +
  • + + Verbindung über SMTP (587) + + +
  • + +
  • + + Verbindung über IMAP (143) + + +
  • + +
  • + + Verbindung über HTTPS (443) + +
  • @@ -2506,6 +2540,19 @@ + + + + + +
  • + + Prüfen Sie nun die Logs auf eine Erneuerung + + + +
  • + +
  • + + Verbindung über SMTP (587) + + +
  • + +
  • + + Verbindung über IMAP (143) + + +
  • + +
  • + + Verbindung über HTTPS (443) + +
  • @@ -2598,8 +2666,6 @@ -

    Erweitertes SSL

    -

    Let's Encrypt (wird mitgeliefert)

    Der "acme-mailcow" Container wird versuchen, ein LE-Zertifikat für ${MAILCOW_HOSTNAME}, autodiscover.ADDED_MAIL_DOMAIN und autoconfig.ADDED_MAIL_DOMAIN zu erhalten.

    @@ -2614,8 +2680,7 @@

    Zusätzliche Domain-Namen

    Bearbeiten Sie "mailcow.conf" und fügen Sie einen Parameter ADDITIONAL_SAN wie folgt hinzu:

    Verwenden Sie keine Anführungszeichen (") und keine Leerzeichen zwischen den Namen!

    -
    ADDITIONAL_SAN=smtp.*,cert1.example.com,cert2.example.org,whatever.*
    -
    +

    ADDITIONAL_SAN=smtp.*,cert1.example.com,cert2.example.org,whatever.*

    Jeder Name wird anhand seiner IPv6-Adresse oder - wenn IPv6 in Ihrer Domäne nicht konfiguriert ist - anhand seiner IPv4-Adresse überprüft.

    Ein Wildcard-Name wie smtp.* wird versuchen, ein smtp.DOMAIN_NAME SAN für jede zu mailcow hinzugefügte Domain zu erhalten.

    Führen Sie docker-compose up -d aus, um betroffene Container automatisch neu zu erstellen.

    @@ -2624,17 +2689,17 @@

    Die Verwendung anderer Namen als MAILCOW_HOSTNAME für den Zugriff auf das mailcow UI kann weitere Konfiguration erfordern.

    Wenn Sie planen, einen anderen Servernamen als MAILCOW_HOSTNAME für den Zugriff auf die mailcow UI zu verwenden (z.B. durch Hinzufügen von mail.* zu ADDITIONAL_SAN), stellen Sie sicher, dass Sie diesen Namen in mailcow.conf über ADDITIONAL_SERVER_NAMES eintragen. Die Namen müssen durch Kommas getrennt sein und dürfen keine Leerzeichen enthalten. Wenn Sie diesen Schritt auslassen, kann mailcow mit einer falschen Seite antworten.

    -
    ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld
    -
    +

    ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld

    Führen Sie docker-compose up -d aus, um es anzuwenden.

    Erneuerung erzwingen

    Um eine Erneuerung zu erzwingen, müssen Sie eine Datei namens force_renew erstellen und den acme-mailcow Container neu starten:

    -
    cd /opt/mailcow-dockerized
    +

    ``` +cd /opt/mailcow-dockerized touch data/assets/ssl/force_renew -docker-compose restart acme-mailcow -# Prüfen Sie nun die Logs auf eine Erneuerung -docker-compose logs --tail=200 -f acme-mailcow -

    +docker-compose restart acme-mailcow

    +

    Prüfen Sie nun die Logs auf eine Erneuerung

    +

    docker-compose logs --tail=200 -f acme-mailcow +```

    Die Datei wird automatisch gelöscht.

    Validierungsfehler und wie man die Validierung überspringt

    Sie können die IP-Überprüfung überspringen, indem Sie SKIP_IP_CHECK=y in mailcow.conf setzen (keine Anführungszeichen). Seien Sie gewarnt, dass eine Fehlkonfiguration dazu führt, dass Sie von Let's Encrypt eingeschränkt werden! Dies ist vor allem für Multi-IP-Setups nützlich, bei denen der IP-Check die falsche Quell-IP-Adresse zurückgeben würde. Aufgrund der Verwendung von dynamischen IPs für acme-mailcow ist Source-NAT bei Neustarts nicht konsistent.

    @@ -2681,35 +2746,33 @@ Sie sollten sicherstellen, dass diese Clients den MAILCOW_HOSTNAME

    Um Ihre eigenen Zertifikate zu verwenden, speichern Sie einfach das kombinierte Zertifikat (mit dem Zertifikat und der zwischengeschalteten CA/CA, falls vorhanden) unter data/assets/ssl/cert.pem und den entsprechenden Schlüssel unter data/assets/ssl/key.pem.

    WICHTIG: Verwenden Sie keine symbolischen Links! Stellen Sie sicher, dass Sie die Zertifikate kopieren und sie nicht mit data/assets/ssl verknüpfen.

    Starten Sie die betroffenen Dienste anschließend neu:

    -
    docker restart $(docker ps -qaf name=postfix-mailcow)
    +

    docker restart $(docker ps -qaf name=postfix-mailcow) docker neu starten $(docker ps -qaf name=nginx-mailcow) -docker restart $(docker ps -qaf name=dovecot-mailcow) -

    +docker restart $(docker ps -qaf name=dovecot-mailcow)

    Siehe Post-Hook-Skript für Nicht-Mailcow-ACME-Clients für ein vollständiges Beispielskript.

    Test gegen das ACME-Verzeichnis

    Bearbeiten Sie mailcow.conf und fügen Sie LE_STAGING=y hinzu.

    Führen Sie docker-compose up -d aus, um Ihre Änderungen zu aktivieren.

    Benutzerdefinierte Verzeichnis-URL

    Editieren Sie mailcow.conf und fügen Sie die entsprechende Verzeichnis-URL in die neue Variable DIRECTORY_URL ein:

    -
    DIRECTORY_URL=https://acme-custom-v9000.api.letsencrypt.org/directory
    -
    +

    DIRECTORY_URL=https://acme-custom-v9000.api.letsencrypt.org/directory

    Sie können LE_STAGING nicht mit DIRECTORY_URL verwenden. Wenn beide gesetzt sind, wird nur LE_STAGING verwendet.

    Führen Sie docker-compose up -d aus, um Ihre Änderungen zu aktivieren.

    Überprüfen Sie Ihre Konfiguration

    Führen Sie docker-compose logs acme-mailcow aus, um herauszufinden, warum eine Validierung fehlschlägt.

    Um zu überprüfen, ob nginx das richtige Zertifikat verwendet, benutzen Sie einfach einen Browser Ihrer Wahl und überprüfen Sie das angezeigte Zertifikat.

    Um das von Postfix, Dovecot und Nginx verwendete Zertifikat zu überprüfen, verwenden wir openssl:

    -
    # Verbindung über SMTP (587)
    -echo "Q" | openssl s_client -starttls smtp -crlf -connect mx.mailcow.email:587
    -# Verbindung über IMAP (143)
    -echo "Q" | openssl s_client -starttls imap -showcerts -connect mx.mailcow.email:143
    -# Verbindung über HTTPS (443)
    -echo "Q" | openssl s_client -connect mx.mailcow.email:443
    -
    +

    ```

    +

    Verbindung über SMTP (587)

    +

    echo "Q" | openssl s_client -starttls smtp -crlf -connect mx.mailcow.email:587

    +

    Verbindung über IMAP (143)

    +

    echo "Q" | openssl s_client -starttls imap -showcerts -connect mx.mailcow.email:143

    +

    Verbindung über HTTPS (443)

    +

    echo "Q" | openssl s_client -connect mx.mailcow.email:443 +```

    Um die von openssl zurückgegebenen Verfallsdaten gegen MAILCOW_HOSTNAME zu validieren, können Sie unser Hilfsskript verwenden:

    -
    cd /opt/mailcow-dockerized
    -bash helper-scripts/expiry-dates.sh
    -
    +

    cd /opt/mailcow-dockerized +bash helper-scripts/expiry-dates.sh


    @@ -2829,7 +2892,7 @@ bash helper-scripts/expiry-dates.sh - + diff --git a/de/post_installation/firststeps-sync_jobs_migration/index.html b/de/post_installation/firststeps-sync_jobs_migration/index.html index ef7682489..40b8c7535 100644 --- a/de/post_installation/firststeps-sync_jobs_migration/index.html +++ b/de/post_installation/firststeps-sync_jobs_migration/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2574,7 +2574,7 @@ - + diff --git a/de/prerequisite/prerequisite-dns/index.html b/de/prerequisite/prerequisite-dns/index.html index 653eb3aeb..504a07c7a 100644 --- a/de/prerequisite/prerequisite-dns/index.html +++ b/de/prerequisite/prerequisite-dns/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -364,27 +364,75 @@
  • + + Name Typ Wert + + + +
  • + + Name Typ Wert + + +
  • + +
  • + + Name Typ Wert + + +
  • + +
  • + + Name Typ Wert + + + +
  • + + Name Typ Priorität Gewicht Port Wert + + + + +
  • + + + + + + +
  • + + ``` + + +
  • + +
  • + + Zusammenfassung der Ergebnisse + + + + +
  • + +
  • + + ``` + + +
  • + +
  • + + Zusammenfassung der Ergebnisse + + +
  • @@ -2371,45 +2380,43 @@ -

    Gitea

    -

    Mit der Fähigkeit von Gitea, sich über SMTP zu authentifizieren, ist es trivial, es mit mailcow zu integrieren. Es sind nur wenige Änderungen erforderlich:

    1. Öffnen Sie docker-compose.override.yml und fügen Sie Gitea hinzu:

    -
    version: '2.1'
    -services:
    -
    -        gitea-mailcow:
    -            image: gitea/gitea:1
    -            volumes:
    -                - ./data/gitea:/data
    -            networks:
    -                mailcow-network:
    -                    aliases:
    -                        - gitea
    -            ports:
    -                - "${GITEA_SSH_PORT:-127.0.0.1:4000}:22"
    -
    +

    ``` +version: '2.1' +services:

    +
        gitea-mailcow:
    +        image: gitea/gitea:1
    +        volumes:
    +            - ./data/gitea:/data
    +        networks:
    +            mailcow-network:
    +                aliases:
    +                    - gitea
    +        ports:
    +            - "${GITEA_SSH_PORT:-127.0.0.1:4000}:22"
    +
    +

    ```

    2. Erstellen Sie data/conf/nginx/site.gitea.custom, fügen Sie folgendes hinzu: -

    location /gitea/ {
    +location /gitea/ {
             proxy_pass http://gitea:3000/;
    -}
    -

    +}

    3. Öffne mailcow.conf und definiere den Port Bind, den Gitea für SSH verwenden soll. Beispiel:

    -
    GITEA_SSH_PORT=127.0.0.1:4000
    -
    +

    GITEA_SSH_PORT=127.0.0.1:4000

    5. Führen Sie docker-compose up -d aus, um den Gitea-Container hochzufahren und führen Sie anschließend docker-compose restart nginx-mailcow aus.

    6. Wenn Sie mailcow zu https gezwungen haben, führen Sie Schritt 9 aus und starten Sie gitea mit docker-compose restart gitea-mailcow neu. Fahren Sie mit Schritt 7 fort (Denken Sie daran, https anstelle von http zu verwenden, https://mx.example.org/gitea/

    7. Öffnen Sie http://${MAILCOW_HOSTNAME}/gitea/, zum Beispiel http://mx.example.org/gitea/. Für die Datenbankdetails stellen Sie mysql als Datenbankhost ein. Verwenden Sie den in mailcow.conf gefundenen Wert von DBNAME als Datenbankname, DBUSER als Datenbankbenutzer und DBPASS als Datenbankpasswort.

    8. Sobald die Installation abgeschlossen ist, loggen Sie sich als Administrator ein und setzen Sie "Einstellungen" -> "Autorisierung" -> "SMTP aktivieren". SMTP-Host sollte postfix mit Port 587 sein, setzen Sie Skip TLS Verify, da wir ein nicht gelistetes SAN verwenden ("postfix" ist höchstwahrscheinlich nicht Teil Ihres Zertifikats).

    9. Erstellen Sie data/gitea/gitea/conf/app.ini und setzen Sie die folgenden Werte. Sie können gitea cheat sheet, leider bisher nur in Englisch verfügbar für deren Bedeutung und andere mögliche Werte konsultieren.

    -
    [server]
    -SSH_LISTEN_PORT = 22
    -# Für GITEA_SSH_PORT=127.0.0.1:4000 in mailcow.conf, setzen:
    -SSH_DOMAIN = 127.0.0.1
    -SSH_PORT = 4000
    -# Für MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (und Standard-Ports für HTTPS), setzen:
    -ROOT_URL = https://mx.example.org/gitea/
    -
    +

    ``` +[server] +SSH_LISTEN_PORT = 22

    +

    Für GITEA_SSH_PORT=127.0.0.1:4000 in mailcow.conf, setzen:

    +

    SSH_DOMAIN = 127.0.0.1 +SSH_PORT = 4000

    +

    Für MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (und Standard-Ports für HTTPS), setzen:

    +

    ROOT_URL = https://mx.example.org/gitea/ +```

    10. Starten Sie gitea neu mit docker-compose restart gitea-mailcow. Ihre Nutzer sollten in der Lage sein, sich mit von mailcow verwalteten Konten anzumelden.


    @@ -2530,7 +2537,7 @@ ROOT_URL = https://mx.example.org/gitea/ - + diff --git a/de/third_party/third_party-gogs/index.html b/de/third_party/third_party-gogs/index.html index 85348700a..360791cc6 100644 --- a/de/third_party/third_party-gogs/index.html +++ b/de/third_party/third_party-gogs/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@
    @@ -2251,6 +2256,8 @@ + + Gogs @@ -2354,6 +2361,8 @@ + +
    @@ -2371,44 +2380,42 @@ -

    Gogs

    -

    Mit Gogs' Fähigkeit, sich über SMTP zu authentifizieren, ist es einfach, es mit mailcow zu verbinden. Es sind nur wenige Änderungen erforderlich:

    1. Öffne docker-compose.override.yml und füge Gogs hinzu:

    -
    version: '2.1'
    -services:
    -
    -    gogs-mailcow:
    -      image: gogs/gogs
    -      volumes:
    -        - ./data/gogs:/data
    -      networks:
    -        mailcow-network:
    -          aliases:
    -            - gogs
    -      ports:
    -        - "${GOGS_SSH_PORT:-127.0.0.1:4000}:22"
    -
    +

    ``` +version: '2.1' +services:

    +
    gogs-mailcow:
    +  image: gogs/gogs
    +  volumes:
    +    - ./data/gogs:/data
    +  networks:
    +    mailcow-network:
    +      aliases:
    +        - gogs
    +  ports:
    +    - "${GOGS_SSH_PORT:-127.0.0.1:4000}:22"
    +
    +

    ```

    2. Erstelle data/conf/nginx/site.gogs.custom, füge hinzu: -

    location /gogs/ {
    +location /gogs/ {
         proxy_pass http://gogs:3000/;
    -}
    -

    +}

    3. Öffne mailcow.conf und definiere die Bindung, die Gogs für SSH verwenden soll. Beispiel:

    -
    GOGS_SSH_PORT=127.0.0.1:4000
    -
    +

    GOGS_SSH_PORT=127.0.0.1:4000

    5. Führen Sie docker-compose up -d aus, um den Gogs-Container hochzufahren und führen Sie anschließend docker-compose restart nginx-mailcow aus.

    6. Öffnen Sie http://${MAILCOW_HOSTNAME}/gogs/, zum Beispiel http://mx.example.org/gogs/. Für Datenbank-Details setzen Sie mysql als Datenbank-Host. Verwenden Sie den in mailcow.conf gefundenen Wert von DBNAME als Datenbankname, DBUSER als Datenbankbenutzer und DBPASS als Datenbankpasswort.

    7. Sobald die Installation abgeschlossen ist, loggen Sie sich als Administrator ein und setzen Sie "Einstellungen" -> "Autorisierung" -> "SMTP aktivieren". SMTP-Host sollte postfix mit Port 587 sein, setzen Sie Skip TLS Verify, da wir ein nicht gelistetes SAN verwenden ("postfix" ist höchstwahrscheinlich nicht Teil Ihres Zertifikats).

    8. Erstellen Sie data/gogs/gogs/conf/app.ini und setzen Sie die folgenden Werte. Sie können Gogs cheat sheet für ihre Bedeutung und andere mögliche Werte konsultieren.

    -
    [server]
    -SSH_LISTEN_PORT = 22
    -# Für GOGS_SSH_PORT=127.0.0.1:4000 in mailcow.conf, setzen:
    -SSH_DOMAIN = 127.0.0.1
    -SSH_PORT = 4000
    -# Für MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (und Standard-Ports für HTTPS), setzen:
    -ROOT_URL = https://mx.example.org/gogs/
    -
    +

    ``` +[server] +SSH_LISTEN_PORT = 22

    +

    Für GOGS_SSH_PORT=127.0.0.1:4000 in mailcow.conf, setzen:

    +

    SSH_DOMAIN = 127.0.0.1 +SSH_PORT = 4000

    +

    Für MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (und Standard-Ports für HTTPS), setzen:

    +

    ROOT_URL = https://mx.example.org/gogs/ +```

    9. Starten Sie Gogs neu mit docker-compose restart gogs-mailcow. Ihre Benutzer sollten in der Lage sein, sich mit von mailcow verwalteten Konten einzuloggen.


    @@ -2529,7 +2536,7 @@ ROOT_URL = https://mx.example.org/gogs/ - + diff --git a/de/third_party/third_party-mailman3/index.html b/de/third_party/third_party-mailman3/index.html index afb189b98..d51df64c6 100644 --- a/de/third_party/third_party-mailman3/index.html +++ b/de/third_party/third_party-mailman3/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2317,162 +2317,6 @@ DNS-Einrichtung - - -
  • - - Installieren Sie Apache als Reverse Proxy - - - - -
  • - -
  • - - Beziehen Sie SSL-Zertifikate mit Let's Encrypt. - - -
  • - -
  • - - Installieren Sie mailcow mit Mailman Integration - - - - -
  • - -
  • - - Installieren Sie Mailman. - - - - -
  • - -
  • - - 🏃 Ausführen - - -
  • - - - - - - -
  • - - Bemerkungen - - - - -
  • - -
  • - - Update - - -
  • - -
  • - - Sicherung - - -
  • - -
  • - - ToDo - - -
  • - -
  • - - Installieren Sie Apache als Reverse Proxy - - - - -
  • - -
  • - - Beziehen Sie SSL-Zertifikate mit Let's Encrypt. - - -
  • - -
  • - - Installieren Sie mailcow mit Mailman Integration - - - - -
  • - -
  • - - Installieren Sie Mailman. - - - - -
  • - -
  • - - 🏃 Ausführen - - -
  • - - - - - - -
  • - - Bemerkungen - - - - -
  • - -
  • - - Update - - -
  • - -
  • - - Sicherung - - -
  • - -
  • - - ToDo - - -
  • Das zu lösende Problem

    mailpiler bietet die Authentifizierung auf Basis von IMAP an, zum Beispiel:

    -
    $config['ENABLE_IMAP_AUTH'] = 1;
    -$config['IMAP_HOST'] = 'mail.example.com';
    -$config['IMAP_PORT'] = 993;
    -$config['IMAP_SSL'] = true;
    -
    +

    php +$config['ENABLE_IMAP_AUTH'] = 1; +$config['IMAP_HOST'] = 'mail.example.com'; +$config['IMAP_PORT'] = 993; +$config['IMAP_SSL'] = true;

    • Wenn Sie sich also mit patrik@example.com anmelden, sehen Sie nur zugestellte E-Mails, die von oder an diese spezielle E-Mail-Adresse gesendet wurden.
    • Wenn zusätzliche Aliase in mailcow definiert werden, wie z.B. team@example.com, werden Sie keine Emails sehen, die an oder von dieser Email-Adresse gesendet wurden, auch wenn Sie ein Empfänger von Emails sind, die an diese Alias-Adresse gesendet wurden.
    • @@ -2515,19 +2515,19 @@
      1. Setzen Sie die benutzerdefinierte Abfragefunktion von mailpiler und fügen Sie diese an /usr/local/etc/piler/config-site.php an:

        -
        $config['MAILCOW_API_KEY'] = 'YOUR_READONLY_API_KEY';
        -$config['MAILCOW_SET_REALNAME'] = true; // wenn nicht angegeben, dann ist der Standardwert false
        -$config['CUSTOM_EMAIL_QUERY_FUNCTION'] = 'query_mailcow_for_email_access';
        -include('auth-mailcow.php');
        -
        +

        php +$config['MAILCOW_API_KEY'] = 'YOUR_READONLY_API_KEY'; +$config['MAILCOW_SET_REALNAME'] = true; // wenn nicht angegeben, dann ist der Standardwert false +$config['CUSTOM_EMAIL_QUERY_FUNCTION'] = 'query_mailcow_for_email_access'; +include('auth-mailcow.php');

        Sie können auch den mailcow-Hostnamen ändern, falls erforderlich: -

        $config['MAILCOW_HOST'] = 'mail.domain.tld'; // standardmäßig $config['IMAP_HOST']
        -

        +php +$config['MAILCOW_HOST'] = 'mail.domain.tld'; // standardmäßig $config['IMAP_HOST']

      2. Laden Sie die PHP-Datei mit den Funktionen aus dem GitHub Repo herunter:

        -
        curl -o /usr/local/etc/piler/auth-mailcow.php https://raw.githubusercontent.com/patschi/mailpiler-mailcow-integration/master/auth-mailcow.php
        -
        +

        sh +curl -o /usr/local/etc/piler/auth-mailcow.php https://raw.githubusercontent.com/patschi/mailpiler-mailcow-integration/master/auth-mailcow.php

      3. Erledigt!

        @@ -2654,7 +2654,7 @@ - + diff --git a/de/third_party/third_party-nextcloud/index.html b/de/third_party/third_party-nextcloud/index.html index 7fca03d5a..d306a763b 100644 --- a/de/third_party/third_party-nextcloud/index.html +++ b/de/third_party/third_party-nextcloud/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2486,14 +2486,13 @@

        Hintergrund-Aufgaben

        Zur Verwendung der empfohlenen Einstellung (Cron) zur Verarbeitung der Hintergrund-Aufgaben müssen in der docker-compose.override.yml folgende Zeilen hinzugefügt werden:

        -
        version: '2.1'
        +

        version: '2.1' services: php-fpm-mailcow: labels: - ofelia.enabled: "true" - ofelia.job-exec.nextcloud-cron.schedule: "@every 5m" - ofelia.job-exec.nextcloud-cron.command: "su www-data -s /bin/bash -c \"/usr/local/bin/php -f /web/nextcloud/cron.php\"" -

        + ofelia.enabled: "true" + ofelia.job-exec.nextcloud-cron.schedule: "@every 5m" + ofelia.job-exec.nextcloud-cron.command: "su www-data -s /bin/bash -c \"/usr/local/bin/php -f /web/nextcloud/cron.php\""

        Nachdem diese Zeilen hinzugefügt wurden muss docker-compose up -d ausgeführt werden, um das Docker Image mit den entsprechenden Labels zu versehen. Danach muss zudem der docker scheduler neu gestartet werden, um den neuen Job zu registrieren. Dazu wird docker-compose restart ofelia-mailcow ausgeführt. Zur Überprüfung, ob die ofelia Konfiguration korrekt ist geladen wurde, kann mittels docker-compose logs ofelia-mailcow nach einer Zeile mit dem Inhalt @@ -2546,14 +2545,12 @@ services:

        Wenn Sie bisher Nextcloud mit mailcow-Authentifizierung über user_external/IMAP verwendet haben, müssen Sie einige zusätzliche Schritte durchführen, um Ihre bestehenden Benutzerkonten mit OAuth2 zu verknüpfen.

        1. Klicken Sie auf die Schaltfläche in der oberen rechten Ecke und wählen Sie Apps. Scrollen Sie nach unten zur App Externe Benutzerauthentifizierung und klicken Sie daneben auf Entfernen. 2. Führen Sie die folgenden Abfragen in Ihrer Nextcloud-Datenbank aus (wenn Sie Nextcloud mit dem Skript von mailcow einrichten, können Sie source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME ausführen): -

        INSERT INTO nc_users (uid, uid_lower) SELECT DISTINCT uid, LOWER(uid) FROM nc_users_external;
        -INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users_external;
        -

        +INSERT INTO nc_users (uid, uid_lower) SELECT DISTINCT uid, LOWER(uid) FROM nc_users_external; +INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users_external;


        Wenn Sie Nextcloud bisher ohne mailcow-Authentifizierung, aber mit den gleichen Benutzernamen wie mailcow genutzt haben, können Sie Ihre bestehenden Benutzerkonten auch mit OAuth2 verknüpfen.

        1. Führen Sie die folgenden Abfragen in Ihrer Nextcloud-Datenbank aus (wenn Sie Nextcloud mit dem Skript von mailcow einrichten, können Sie source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME ausführen): -

        INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users;
        -

        +INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users;


        Aktualisieren

        Die Nextcloud-Instanz kann einfach mit dem Web-Update-Mechanismus aktualisiert werden. Bei größeren Updates können nach dem Update weitere Änderungen vorgenommen werden. Nachdem die Nextcloud-Instanz geprüft wurde, werden Probleme angezeigt. Dies können z.B. fehlende Indizes in der DB oder ähnliches sein. @@ -2563,13 +2560,12 @@ Es wird angezeigt, welche Befehle ausgeführt werden müssen, diese müssen im p


        Fehlersuche und Fehlerbehebung

        Es kann vorkommen, dass Sie die Nextcloud-Instanz von Ihrem Netzwerk aus nicht erreichen können. Dies kann daran liegen, dass der Eintrag Ihres Subnetzes im Array 'trusted_proxies' fehlt. Sie können Änderungen in der Nextcloud config.php in data/web/nextcloud/config/* vornehmen.

        -
        'trusted_proxies' =>
        +

        'trusted_proxies' => array ( - 0 => 'fd4d:6169:6c63:6f77::/64', - 1 => '172.22.1.0/24', - 2 => 'NewSubnet/24', - ), -

        + 0 => 'fd4d:6169:6c63:6f77::/64', + 1 => '172.22.1.0/24', + 2 => 'NewSubnet/24', + ),

        Nachdem die Änderungen vorgenommen wurden, muss der nginx-Container neu gestartet werden. docker-compose restart nginx-mailcow

        @@ -2691,7 +2687,7 @@ Es wird angezeigt, welche Befehle ausgeführt werden müssen, diese müssen im p - + diff --git a/de/third_party/third_party-portainer/index.html b/de/third_party/third_party-portainer/index.html index 78118ae0a..b0a23fcd2 100644 --- a/de/third_party/third_party-portainer/index.html +++ b/de/third_party/third_party-portainer/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2375,7 +2375,7 @@

        Um Portainer zu aktivieren, müssen die docker-compose.yml und site.conf für Nginx geändert werden.

        1. Erstellen Sie eine neue Datei docker-compose.override.yml im mailcow-dockerized Stammverzeichnis und fügen Sie die folgende Konfiguration ein -

        version: '2.1'
        +version: '2.1'
         services:
             portainer-mailcow:
               image: portainer/portainer-ce
        @@ -2389,42 +2389,40 @@ services:
               networks:
                 mailcow-network:
                   aliases:
        -            - portainer
        -
        + - portainer 2a. Erstelle data/conf/nginx/portainer.conf: -
        upstream portainer {
        +```
        +upstream portainer {
           server portainer-mailcow:9000;
        -}
        -
        -map $http_upgrade $connection_upgrade {
        +}

        +

        map $http_upgrade $connection_upgrade { default upgrade; - '' close; + '' close; } -

        +```

        2b. Fügen Sie einen neuen Standort für die Standard-Mailcow-Site ein, indem Sie die Datei data/conf/nginx/site.portainer.custom erstellen: -

          location /portainer/ {
        +```
        +  location /portainer/ {
             proxy_http_version 1.1;
        -    proxy_set_header Host              $http_host;   # required for docker client's sake
        -    proxy_set_header X-Real-IP         $remote_addr; # pass on real client's IP
        +    proxy_set_header Host              $http_host;   # required for docker client's sake
        +    proxy_set_header X-Real-IP         $remote_addr; # pass on real client's IP
             proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
             proxy_set_header X-Forwarded-Proto $scheme;
        -    proxy_read_timeout                 900;
        -
        -    proxy_set_header Connection "";
        -    proxy_buffers 32 4k;
        -    proxy_pass http://portainer/;
        -  }
        -
        -  location /portainer/api/websocket/ {
        +    proxy_read_timeout                 900;

        +
        proxy_set_header Connection "";
        +proxy_buffers 32 4k;
        +proxy_pass http://portainer/;
        +
        +

        }

        +

        location /portainer/api/websocket/ { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; - proxy_pass http://portainer/api/websocket/; + proxy_pass http://portainer/api/websocket/; } -

        +```

        3. Übernehmen Sie Ihre Änderungen: -

        docker-compose up -d && docker-compose restart nginx-mailcow
        -

        +docker-compose up -d && docker-compose restart nginx-mailcow

        Nun können Sie einfach zu https://${MAILCOW_HOSTNAME}/portainer/ navigieren, um Ihre Portainer-Container-Überwachungsseite anzuzeigen. Sie werden dann aufgefordert, ein neues Passwort für den admin Account anzugeben. Nachdem Sie Ihr Passwort eingegeben haben, können Sie sich mit der Portainer UI verbinden.


        @@ -2545,7 +2543,7 @@ map $http_upgrade $connection_upgrade { - + diff --git a/de/third_party/third_party-roundcube/index.html b/de/third_party/third_party-roundcube/index.html index 1d3fe9ba0..819fe98e8 100644 --- a/de/third_party/third_party-roundcube/index.html +++ b/de/third_party/third_party-roundcube/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2357,38 +2357,134 @@
      4. + + Prüfen Sie, ob eine neuere Version vorliegt! + + +
      5. + +
      6. + + Ändern Sie den Ordnernamen + + +
      7. + +
      8. + + Berechtigungen ändern + + +
      9. + +
      10. + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) sollte in 1.6 nicht erforderlich sein + + +
      11. + +
      12. + + !/bin/bash + + + +
      13. + + Starten Sie eine Bash-Sitzung des mailcow PHP-Containers + + +
      14. + +
      15. + + Installieren Sie die erforderliche Upgrade-Abhängigkeit, dann aktualisieren Sie Roundcube auf die gewünschte Version + + +
      16. + +
      17. + + Geben Sie 'Y' ein und drücken Sie die Eingabetaste, um Ihre Installation von Roundcube zu aktualisieren. + + +
      18. + +
      19. + + Entfernen Sie übrig gebliebene Dateien + + +
      20. + +
      21. + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) sollte in 1.6 nicht benötigt werden + + + + +
      22. + +
      23. + + Erlaube Admins, sich in Roundcube als Email-Benutzer einzuloggen (ohne Passwort) + + +
      24. + +
      25. + + Roundcube mit Plugin dovecot_impersonate muss zuerst installiert werden + +
    @@ -2438,38 +2534,134 @@
  • + + Prüfen Sie, ob eine neuere Version vorliegt! + + +
  • + +
  • + + Ändern Sie den Ordnernamen + + +
  • + +
  • + + Berechtigungen ändern + + +
  • + +
  • + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) sollte in 1.6 nicht erforderlich sein + + +
  • + +
  • + + !/bin/bash + + + +
  • + + Starten Sie eine Bash-Sitzung des mailcow PHP-Containers + + +
  • + +
  • + + Installieren Sie die erforderliche Upgrade-Abhängigkeit, dann aktualisieren Sie Roundcube auf die gewünschte Version + + +
  • + +
  • + + Geben Sie 'Y' ein und drücken Sie die Eingabetaste, um Ihre Installation von Roundcube zu aktualisieren. + + +
  • + +
  • + + Entfernen Sie übrig gebliebene Dateien + + +
  • + +
  • + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) sollte in 1.6 nicht benötigt werden + + + + +
  • + +
  • + + Erlaube Admins, sich in Roundcube als Email-Benutzer einzuloggen (ohne Passwort) + + +
  • + +
  • + + Roundcube mit Plugin dovecot_impersonate muss zuerst installiert werden + +
  • @@ -2490,124 +2682,114 @@ -

    Roundcube

    -

    Installation von Roundcube

    Laden Sie Roundcube 1.5.x in das Web htdocs Verzeichnis herunter und entpacken Sie es (hier rc/): -

    # Prüfen Sie, ob eine neuere Version vorliegt!
    -cd daten/web
    -wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz -
    -
    -# Ändern Sie den Ordnernamen
    -mv roundcubemail-1.5.2 rc
    -
    -# Berechtigungen ändern
    -chown -R root: rc/
    -
    -# Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) sollte in 1.6 nicht erforderlich sein
    -sed -i "s/\$prefix = '\.\/';/\$prefix = preg_replace\('\/\[\?\&]\.\*\$\/', '', \$_SERVER\['REQUEST_URI'] \?\? ''\) \?: '\.\/';/g" rc/program/include/rcmail.php
    -

    +```

    +

    Prüfen Sie, ob eine neuere Version vorliegt!

    +

    cd daten/web +wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz -

    +

    Ändern Sie den Ordnernamen

    +

    mv roundcubemail-1.5.2 rc

    +

    Berechtigungen ändern

    +

    chown -R root: rc/

    +

    Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) sollte in 1.6 nicht erforderlich sein

    +

    sed -i "s/\$prefix = '.\/';/\$prefix = preg_replace('\/[\?\&].*\$\/', '', \$_SERVER['REQUEST_URI'] \?\? '') \?: '.\/';/g" rc/program/include/rcmail.php +```

    Wenn Sie eine Rechtschreibprüfung benötigen, erstellen Sie eine Datei data/hooks/phpfpm/aspell.sh mit folgendem Inhalt und geben Sie dann chmod +x data/hooks/phpfpm/aspell.sh ein. Dadurch wird eine lokale Rechtschreibprüfung installiert. Beachten Sie, dass die meisten modernen Webbrowser eine eingebaute Rechtschreibprüfung haben, so dass Sie diese vielleicht nicht benötigen. -

    #!/bin/bash
    -apk update
    +```

    +

    !/bin/bash

    +

    apk update apk add aspell-de # oder jede andere Sprache -

    +```

    Erstellen Sie eine Datei data/web/rc/config/config.inc.php mit dem folgenden Inhalt. - Ändern Sie den Parameter des_key auf einen Zufallswert. Er wird verwendet, um Ihr IMAP-Passwort vorübergehend zu speichern. - Der db_prefix ist optional, wird aber empfohlen. - Wenn Sie die Rechtschreibprüfung im obigen Schritt nicht installiert haben, entfernen Sie den Parameter spellcheck_engine und ersetzen ihn durch $config['enable_spellcheck'] = false;. -

    <?php
    +<?php
     error_reporting(0);
    -if (!file_exists('/tmp/mime.types')) {
    -file_put_contents("/tmp/mime.types", fopen("http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types", 'r'));
    +if (!file_exists('/tmp/mime.types')) {
    +file_put_contents("/tmp/mime.types", fopen("http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types", 'r'));
     }
     $config = array();
    -$config['db_dsnw'] = 'mysql://' . getenv('DBUSER') . ':' . getenv('DBPASS') . '@mysql/' . getenv('DBNAME');
    -$config['default_host'] = 'tls://dovecot';
    -$config['default_port'] = '143';
    -$config['smtp_server'] = 'tls://postfix';
    -$config['smtp_port'] = 587;
    -$config['smtp_user'] = '%u';
    -$config['smtp_pass'] = '%p';
    -$config['support_url'] = '';
    -$config['product_name'] = 'Roundcube Webmail';
    -$config['des_key'] = 'yourrandomstring_changeme';
    -$config['log_dir'] = '/dev/null';
    -$config['temp_dir'] = '/tmp';
    -$config['plugins'] = array(
    -  'archive',
    -  'managesieve'
    +$config['db_dsnw'] = 'mysql://' . getenv('DBUSER') . ':' . getenv('DBPASS') . '@mysql/' . getenv('DBNAME');
    +$config['default_host'] = 'tls://dovecot';
    +$config['default_port'] = '143';
    +$config['smtp_server'] = 'tls://postfix';
    +$config['smtp_port'] = 587;
    +$config['smtp_user'] = '%u';
    +$config['smtp_pass'] = '%p';
    +$config['support_url'] = '';
    +$config['product_name'] = 'Roundcube Webmail';
    +$config['des_key'] = 'yourrandomstring_changeme';
    +$config['log_dir'] = '/dev/null';
    +$config['temp_dir'] = '/tmp';
    +$config['plugins'] = array(
    +  'archive',
    +  'managesieve'
     );
    -$config['spellcheck_engine'] = 'aspell';
    -$config['mime_types'] = '/tmp/mime.types';
    -$config['imap_conn_options'] = array(
    -  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
    +$config['spellcheck_engine'] = 'aspell';
    +$config['mime_types'] = '/tmp/mime.types';
    +$config['imap_conn_options'] = array(
    +  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
     );
    -$config['enable_installer'] = true;
    -$config['smtp_conn_options'] = array(
    -  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
    +$config['enable_installer'] = true;
    +$config['smtp_conn_options'] = array(
    +  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
     );
    -$config['db_prefix'] = 'mailcow_rc1';
    -

    +$config['db_prefix'] = 'mailcow_rc1';

    Richten Sie Ihren Browser auf https://myserver/rc/installer und folgen Sie den Anweisungen. Initialisiere die Datenbank und verlasse das Installationsprogramm.

    **Löschen Sie das Verzeichnis data/web/rc/installer nach einer erfolgreichen Installation!

    Konfigurieren Sie die ManageSieve-Filterung

    Öffnen Sie data/web/rc/plugins/managesieve/config.inc.php und ändern Sie die folgenden Parameter (oder fügen Sie sie am Ende der Datei hinzu): -

    $config['managesieve_port'] = 4190;
    -$config['managesieve_host'] = 'tls://dovecot';
    -$config['managesieve_conn_options'] = array(
    -  ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
    +$config['managesieve_port'] = 4190;
    +$config['managesieve_host'] = 'tls://dovecot';
    +$config['managesieve_conn_options'] = array(
    +  ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
     );
     // Aktiviert separate Verwaltungsschnittstelle für Urlaubsantworten (außer Haus)
     // 0 - kein separater Abschnitt (Standard),
    -// 1 - Abschnitt "Urlaub" hinzufügen,
    -// 2 - Abschnitt "Urlaub" hinzufügen, aber Abschnitt "Filter" ausblenden
    -$config['managesieve_vacation'] = 1;
    -

    +// 1 - Abschnitt "Urlaub" hinzufügen, +// 2 - Abschnitt "Urlaub" hinzufügen, aber Abschnitt "Filter" ausblenden +$config['managesieve_vacation'] = 1;

    Aktivieren Sie die Funktion "Passwort ändern" in Roundcube

    Öffnen Sie data/web/rc/config/config.inc.php und aktivieren Sie das Passwort-Plugin:

    -
    [...]
    -$config['plugins'] = array(
    -    'archive',
    -    'password',
    +

    [...] +$config['plugins'] = array( + 'archive', + 'password', ); -[...] -

    +[...]

    Öffnen Sie data/web/rc/plugins/password/password.php, suchen Sie nach case 'ssha': und fügen Sie oben hinzu:

    -
            case 'ssha256':
    +

    case 'ssha256': $salt = rcube_utils::random_bytes(8); - $crypted = base64_encode( hash('sha256', $password . $salt, TRUE ) . $salt ); - $prefix = '{SSHA256}'; - break; -

    + $crypted = base64_encode( hash('sha256', $password . $salt, TRUE ) . $salt ); + $prefix = '{SSHA256}'; + break;

    Öffnen Sie data/web/rc/plugins/password/config.inc.php und ändern Sie die folgenden Parameter (oder fügen Sie sie am Ende der Datei hinzu):

    -
    $config['password_driver'] = 'sql';
    -$config['password_algorithm'] = 'ssha256';
    -$config['password_algorithm_prefix'] = '{SSHA256}';
    -$config['password_query'] = "UPDATE mailbox SET password = %P WHERE username = %u";
    -
    +

    $config['password_driver'] = 'sql'; +$config['password_algorithm'] = 'ssha256'; +$config['password_algorithm_prefix'] = '{SSHA256}'; +$config['password_query'] = "UPDATE mailbox SET password = %P WHERE username = %u";

    CardDAV Adressbücher in Roundcube einbinden

    Laden Sie die neueste Version von RCMCardDAV in das Roundcube Plugin Verzeichnis und entpacken Sie es (hier rc/plugins): -

    cd data/web/rc/plugins
    +cd data/web/rc/plugins
     wget -O - https://github.com/mstilkerich/rcmcarddav/releases/download/v4.3.0/carddav-v4.3.0.tar.gz | tar xfvz -
    -chown -R root: carddav/
    -

    +chown -R root: carddav/

    Kopieren Sie die Datei config.inc.php.dist nach config.inc.php (hier in rc/plugins/carddav) und fügen Sie die folgende Voreinstellung an das Ende der Datei an - vergessen Sie nicht, mx.example.org durch Ihren eigenen Hostnamen zu ersetzen: -

    $prefs['SOGo'] = array(
    -    'name'         =>  'SOGo',
    -    'username'     =>  '%u',
    -    'password'     =>  '%p',
    -    'url'          =>  'https://mx.example.org/SOGo/dav/%u/',
    -    'carddav_name_only' => true,
    -    'use_categories' => true,
    -    'active'       =>  true,
    -    'readonly'     =>  false,
    -    'refresh_time' => '02:00:00',
    -    'fixed'        =>  array( 'active', 'name', 'username', 'password', 'refresh_time' ),
    -    'hide'        =>  false,
    -);
    -
    +$prefs['SOGo'] = array( + 'name' => 'SOGo', + 'username' => '%u', + 'password' => '%p', + 'url' => 'https://mx.example.org/SOGo/dav/%u/', + 'carddav_name_only' => true, + 'use_categories' => true, + 'active' => true, + 'readonly' => false, + 'refresh_time' => '02:00:00', + 'fixed' => array( 'active', 'name', 'username', 'password', 'refresh_time' ), + 'hide' => false, +); Bitte beachten Sie, dass dieses Preset nur das Standard-Adressbuch integriert (dasjenige, das den Namen "Persönliches Adressbuch" trägt und nicht gelöscht werden kann). Weitere Adressbücher werden derzeit nicht automatisch erkannt, können aber manuell in den Roundcube-Einstellungen hinzugefügt werden.

    Aktivieren Sie das Plugin, indem Sie carddav zu $config['plugins'] in rc/config/config.inc.php hinzufügen.

    Wenn Sie die Standard-Adressbücher (die in der Roundcube-Datenbank gespeichert sind) entfernen möchten, so dass nur die CardDAV-Adressbücher zugänglich sind, fügen Sie $config['address_book_type'] = ''; in die Konfigurationsdatei data/web/rc/config/config.inc.php ein.

    @@ -2615,75 +2797,70 @@ Bitte beachten Sie, dass dieses Preset nur das Standard-Adressbuch integriert (d

    Optional können Sie Roundcube's Link zu der mailcow Apps Liste hinzufügen. Um dies zu tun, öffnen oder erstellen Sie data/web/inc/vars.local.inc.php und fügen Sie den folgenden Code-Block hinzu:

    HINWEIS: Vergessen Sie nicht, das <?php Trennzeichen in der ersten Zeile einzufügen

    -
    ...
    +

    ... $MAILCOW_APPS = array( array( - 'name' => 'SOGo', - 'link' => '/SOGo/' + 'name' => 'SOGo', + 'link' => '/SOGo/' ), array( - 'name' => 'Roundcube', - 'link' => '/rc/' + 'name' => 'Roundcube', + 'link' => '/rc/' ) ); -... -

    +...

    Aktualisierung von Roundcube

    Ein Upgrade von Roundcube ist recht einfach: Gehen Sie auf die Github releases Seite für Roundcube und holen Sie sich den Link für die "complete.tar.gz" Datei für die gewünschte Version. Dann folgen Sie den untenstehenden Befehlen und ändern Sie die URL und den Namen des Roundcube-Ordners, falls nötig.

    -
    # Starten Sie eine Bash-Sitzung des mailcow PHP-Containers
    -docker exec -it mailcowdockerized_php-fpm-mailcow_1 bash
    -
    -# Installieren Sie die erforderliche Upgrade-Abhängigkeit, dann aktualisieren Sie Roundcube auf die gewünschte Version
    -apk add rsync
    +

    ```

    +

    Starten Sie eine Bash-Sitzung des mailcow PHP-Containers

    +

    docker exec -it mailcowdockerized_php-fpm-mailcow_1 bash

    +

    Installieren Sie die erforderliche Upgrade-Abhängigkeit, dann aktualisieren Sie Roundcube auf die gewünschte Version

    +

    apk add rsync cd /tmp -wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz - +wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz - cd roundcubemail-1.5.2 -bin/installto.sh /web/rc - -# Geben Sie 'Y' ein und drücken Sie die Eingabetaste, um Ihre Installation von Roundcube zu aktualisieren. - -# Entfernen Sie übrig gebliebene Dateien -cd /tmp -rm -rf roundcube* - -# Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) sollte in 1.6 nicht benötigt werden -sed -i "s/\$prefix = '\.\/';/\$prefix = preg_replace\('\/\[\?\&]\.\*\$\/', '', \$_SERVER\['REQUEST_URI'] \?\? ''\) \?: '\.\/';/g" /web/rc/program/include/rcmail.php -

    +bin/installto.sh /web/rc

    +

    Geben Sie 'Y' ein und drücken Sie die Eingabetaste, um Ihre Installation von Roundcube zu aktualisieren.

    +

    Entfernen Sie übrig gebliebene Dateien

    +

    cd /tmp +rm -rf roundcube*

    +

    Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) sollte in 1.6 nicht benötigt werden

    +

    sed -i "s/\$prefix = '.\/';/\$prefix = preg_replace('\/[\?\&].*\$\/', '', \$_SERVER['REQUEST_URI'] \?\? '') \?: '.\/';/g" /web/rc/program/include/rcmail.php +```

    Administratoren ohne Passwort in Roundcube einloggen lassen

    Installieren Sie zunächst das Plugin [dovecot_impersonate] (https://github.com/corbosman/dovecot_impersonate/) und fügen Sie Roundcube als App hinzu (siehe oben).

    Editieren Sie mailcow.conf und fügen Sie folgendes hinzu:

    -
    # Erlaube Admins, sich in Roundcube als Email-Benutzer einzuloggen (ohne Passwort)
    -# Roundcube mit Plugin dovecot_impersonate muss zuerst installiert werden
    -
    -ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=y
    -
    +

    ```

    +

    Erlaube Admins, sich in Roundcube als Email-Benutzer einzuloggen (ohne Passwort)

    +

    Roundcube mit Plugin dovecot_impersonate muss zuerst installiert werden

    +

    ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=y +```

    Editieren Sie docker-compose.override.yml und verfassen/erweitern Sie den Abschnitt für php-fpm-mailcow:

    -
    version: '2.1'
    +

    yml +version: '2.1' services: php-fpm-mailcow: environment: - - ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=${ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE:-n} -

    + - ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=${ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE:-n}

    Bearbeiten Sie data/web/js/site/mailbox.js und den folgenden Code nach if (ALLOW_ADMIN_EMAIL_LOGIN) { ... }

    -
    if (ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE) {
    -  item.action += '<a href="/rc-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs ' + btnSize + ' btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> Roundcube</a>';
    -}
    -
    +

    js +if (ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE) { + item.action += '<a href="/rc-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs ' + btnSize + ' btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> Roundcube</a>'; +}

    Bearbeiten Sie data/web/mailbox.php und fügen Sie diese Zeile zum Array $template_data hinzu:

    -
      'allow_admin_email_login_roundcube' => (preg_match("/^(yes|y)+$/i", $_ENV["ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE"])) ? 'true' : 'false',
    -
    +

    php + 'allow_admin_email_login_roundcube' => (preg_match("/^(yes|y)+$/i", $_ENV["ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE"])) ? 'true' : 'false',

    Bearbeiten Sie data/web/templates/mailbox.twig und fügen Sie diesen Code am Ende des [javascript-Abschnitts] ein (https://github.com/mailcow/mailcow-dockerized/blob/2f9da5ae93d93bf62a8c2b7a5a6ae50a41170c48/data/web/templates/mailbox.twig#L49-L57):

    -
      var ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE = {{ allow_admin_email_login_roundcube }};
    -
    +

    js + var ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE = {{ allow_admin_email_login_roundcube }};

    Kopieren Sie den Inhalt der folgenden Dateien aus diesem Snippet:

    • data/web/inc/lib/RoundcubeAutoLogin.php
    • data/web/rc-auth.php

    Starten Sie schließlich mailcow neu

    -
    docker-compose down
    -docker-compose up -d
    -
    +

    docker-compose down +docker-compose up -d


    @@ -2788,7 +2965,7 @@ docker-compose up -d - + diff --git a/de/troubleshooting/debug-admin_login_sogo/index.html b/de/troubleshooting/debug-admin_login_sogo/index.html index c8a5480ea..f5d8739f9 100644 --- a/de/troubleshooting/debug-admin_login_sogo/index.html +++ b/de/troubleshooting/debug-admin_login_sogo/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2455,11 +2455,9 @@ Dazu wird ein zusätzlicher Link zu SOGo in der Mailbox-Liste (mailcow UI) angez

    Auch mehrere gleichzeitige Admin-Logins auf verschiedene Postfächer sind mit dieser Funktion möglich.

    Aktivieren der Funktion

    Die Funktion ist standardmäßig deaktiviert. Es kann in der mailcow.conf durch Setzen aktiviert werden: -

    ALLOW_ADMIN_EMAIL_LOGIN=y
    -
    +ALLOW_ADMIN_EMAIL_LOGIN=y und die betroffenen Container neu erstellen mit -
    docker-compose up -d
    -

    +docker-compose up -d

    Nachteile bei Aktivierung

    • Jeder SOGo-Seiten-Load und jede Active-Sync-Anfrage verursacht eine zusätzliche Ausführung eines internen PHP-Skripts. @@ -2605,7 +2603,7 @@ In den meisten Fällen sollte dies nicht spürbar sein, aber Sie sollten es im H - + diff --git a/de/troubleshooting/debug-attach_service/index.html b/de/troubleshooting/debug-attach_service/index.html index 94da165d8..36ef49878 100644 --- a/de/troubleshooting/debug-attach_service/index.html +++ b/de/troubleshooting/debug-attach_service/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2504,17 +2504,14 @@

      Anhängen eines Containers an Ihre Shell

      Um einen Container an Ihre Shell anzuhängen, können Sie einfach folgendes ausführen

      -
      docker-compose exec $Dienst_Name /bin/bash
      -
      +

      docker-compose exec $Dienst_Name /bin/bash

      Verbindung zu Diensten herstellen

      Wenn Sie sich direkt mit einem Dienst / einer Anwendung verbinden wollen, ist es immer eine gute Idee, source mailcow.conf zu benutzen, um alle relevanten Variablen in Ihre Umgebung zu bekommen.

      MySQL

      -
      Quelle mailcow.conf
      -docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
      -
      +

      Quelle mailcow.conf +docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}

      Redis

      -
      docker-compose exec redis-mailcow redis-cli
      -
      +

      docker-compose exec redis-mailcow redis-cli

      Dienstbeschreibungen

      Hier ist eine kurze Übersicht, welcher Container / Dienst was macht:

      @@ -2710,7 +2707,7 @@ docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} - + diff --git a/de/troubleshooting/debug-common_problems/index.html b/de/troubleshooting/debug-common_problems/index.html index 1b00f7cf7..2b3dd01c5 100644 --- a/de/troubleshooting/debug-common_problems/index.html +++ b/de/troubleshooting/debug-common_problems/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -801,52 +801,65 @@
    • + + telnet 74.125.133.27 465 + + + +
    • @@ -2466,52 +2479,65 @@
    • + + telnet 74.125.133.27 465 + + + +
    • @@ -2532,8 +2558,6 @@ -

      Häufig auftretende Probleme

      -

      Hier sind häufige Probleme und mögliche Lösungen:

      Mail kommt in einer Schleife zu sich selbst zurück.

      Bitte überprüfen Sie in Ihrer mailcow UI, ob Sie die Domain als Backup MX eingestellt haben: @@ -2544,11 +2568,12 @@

    • Prüfen Sie, ob Ihre IP-Adresse auf einer schwarzen Liste steht. Sie können dnsbl.info oder einen ähnlichen Dienst verwenden, um Ihre IP-Adresse zu überprüfen.
    • Es gibt einige ISP-Router, die Mail-Ports für nicht auf der Blacklist stehende Domains blockieren. Bitte überprüfen Sie, ob Sie Ihren Server über die Ports 465 oder 587 erreichen können:
    • -
      # telnet 74.125.133.27 465
      -Versucht 74.125.133.27...
      +

      ```

      +

      telnet 74.125.133.27 465

      +

      Versucht 74.125.133.27... Verbunden mit 74.125.133.27. -Escape-Zeichen ist '^]'. -

      +Escape-Zeichen ist '^]'. +```

      Meine Mails werden als Spam identifiziert

      Bitte lesen Sie unsere DNS-Konfiguration Anleitung.

      docker-compose wirft seltsame Fehler aus.

      @@ -2565,8 +2590,7 @@ Escape-Zeichen ist '^]'.

      Es könnte auch eine falsch verknüpfte Datei sein (z. B. ein SSL-Zertifikat), die den Start eines wichtigen Containers (nginx) verhindert. Prüfen Sie daher immer Ihre Protokolle, um herauszufinden, woher das Problem kommt.

      Adresse bereits in Gebrauch

      Wenn Sie eine Fehlermeldung erhalten wie:

      -
      ERROR: for postfix-mailcow Cannot start service postfix-mailcow: driver failed programming external connectivity on endpoint mailcowdockerized_postfix-mailcow_1: Error starting userland proxy: listen tcp 0.0.0:25: bind: address already in use
      -
      +

      ERROR: for postfix-mailcow Cannot start service postfix-mailcow: driver failed programming external connectivity on endpoint mailcowdockerized_postfix-mailcow_1: Error starting userland proxy: listen tcp 0.0.0:25: bind: address already in use

      während Sie versuchen, mailcow: dockerized zu starten / zu installieren, stellen Sie sicher, dass Sie unseren Abschnitt über prerequisites befolgt haben.

      XYZ kann keine Verbindung zu ...

      Bitte überprüfen Sie Ihre lokale Firewall! @@ -2574,19 +2598,17 @@ Docker und iptables-basierte Firewalls erstellen manchmal widersprüchliche Rege

      Wenn Sie Verbindungsprobleme von zu Hause aus haben, überprüfen Sie bitte auch die Firewall Ihres ISP-Routers, da einige von ihnen den E-Mail-Verkehr über die Ports SMTP (587) oder SMTPS (465) blockieren. Es könnte auch sein, dass Ihr ISP die Ports für SUBMISSION (25) blockiert.

      Während Linux-Benutzer aus einer Vielzahl von Tools1 wählen können, um zu überprüfen, ob ein Port offen ist, steht Windows-Benutzern standardmäßig nur der PowerShell-Befehl Test-NetConnection -ComputerName host -Port port zur Verfügung.

      Um Telnet auf einem Windows nach Vista zu aktivieren, lesen Sie bitte diese Anleitung oder geben Sie den folgenden Befehl in einem Terminal mit Administratorrechten ein:

      -
      dism /online /Enable-Feature /FeatureName:TelnetClient
      -
      +

      dism /online /Enable-Feature /FeatureName:TelnetClient

      Inotify-Instanz-Limit überschritten für Benutzer 5000 (UID vmail) (siehe #453).

      Docker-Container verwenden die inotify-Limits von Docker-Hosts. Wenn Sie sie auf Ihrem Docker-Host setzen, werden sie an den Container weitergegeben.

      Dovecot startet ständig neu (siehe #2672).

      Stellen Sie sicher, dass Sie mindestens die folgenden Dateien in data/assets/ssl haben:

      -
      cert.pem
      +

      cert.pem dhparams.pem -key.pem -

      +key.pem

      Wenn dhparams.pem fehlt, können Sie es mit Bash

      -
      openssl dhparam -out data/assets/ssl/dhparams.pem 4096
      -
      +

      bash +openssl dhparam -out data/assets/ssl/dhparams.pem 4096


        @@ -2714,7 +2736,7 @@ key.pem - + diff --git a/de/troubleshooting/debug-logs/index.html b/de/troubleshooting/debug-logs/index.html index 8489cbdd3..a344d6d53 100644 --- a/de/troubleshooting/debug-logs/index.html +++ b/de/troubleshooting/debug-logs/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2508,7 +2508,7 @@ - + diff --git a/de/troubleshooting/debug-mysql_aria/index.html b/de/troubleshooting/debug-mysql_aria/index.html index b4125438d..81b769610 100644 --- a/de/troubleshooting/debug-mysql_aria/index.html +++ b/de/troubleshooting/debug-mysql_aria/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -833,6 +833,41 @@ MariaDB: Aria-Wiederherstellung nach Absturz + + +
      1. + + Stoppe den Stack, führe nicht "down" aus + + +
      2. + +
      3. + + Führen Sie eine Bash in dem gestoppten Container als Benutzer mysql aus + + +
      4. + +
      5. + + cd in das SQL-Datenverzeichnis + + +
      6. + +
      7. + + aria_chk ausführen + + +
      8. + +
      9. + + Löschen der aria-Logdateien + +
      10. @@ -2400,6 +2435,41 @@ MariaDB: Aria-Wiederherstellung nach Absturz + + +
      11. + + Stoppe den Stack, führe nicht "down" aus + + +
      12. + +
      13. + + Führen Sie eine Bash in dem gestoppten Container als Benutzer mysql aus + + +
      14. + +
      15. + + cd in das SQL-Datenverzeichnis + + +
      16. + +
      17. + + aria_chk ausführen + + +
      18. + +
      19. + + Löschen der aria-Logdateien + +
      20. @@ -2420,23 +2490,22 @@ -

        Abgestürzte Aria-Speicher-Engine wiederherstellen

        -

        MariaDB: Aria-Wiederherstellung nach Absturz

        Wenn Ihr Server abgestürzt ist und MariaDB eine Fehlermeldung ähnlich [ERROR] mysqld: Aria recovery failed. Please run aria_chk -r on all Aria tables (*.MAI) and delete all aria_log.######## files, können Sie Folgendes versuchen, um die Datenbank in einen gesunden Zustand zu bringen:

        Starten Sie den Stack und warten Sie, bis mysql-mailcow beginnt, einen Neustart zu melden. Überprüfen Sie dies, indem Sie docker-compose ps ausführen.

        Führen Sie nun die folgenden Befehle aus:

        -
        # Stoppe den Stack, führe nicht "down" aus
        -docker-compose stop
        -# Führen Sie eine Bash in dem gestoppten Container als Benutzer mysql aus
        -docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql bash"' mysql-mailcow
        -# cd in das SQL-Datenverzeichnis
        -cd /var/lib/mysql
        -# aria_chk ausführen
        -aria_chk --check --force */*.MAI
        -# Löschen der aria-Logdateien
        -rm aria_log.*
        -
        +

        ```

        +

        Stoppe den Stack, führe nicht "down" aus

        +

        docker-compose stop

        +

        Führen Sie eine Bash in dem gestoppten Container als Benutzer mysql aus

        +

        docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql bash"' mysql-mailcow

        +

        cd in das SQL-Datenverzeichnis

        +

        cd /var/lib/mysql

        +

        aria_chk ausführen

        +

        aria_chk --check --force /.MAI

        +

        Löschen der aria-Logdateien

        +

        rm aria_log.* +```

        Führen Sie nun docker-compose down gefolgt von docker-compose up -d aus.


        @@ -2557,7 +2626,7 @@ rm aria_log.* - + diff --git a/de/troubleshooting/debug-mysql_upgrade/index.html b/de/troubleshooting/debug-mysql_upgrade/index.html index 13ada1b59..8b16c02cb 100644 --- a/de/troubleshooting/debug-mysql_upgrade/index.html +++ b/de/troubleshooting/debug-mysql_upgrade/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2424,13 +2424,11 @@

        Führen Sie ein manuelles mysql_upgrade durch.

        Dieser Schritt ist normalerweise nicht notwendig.

        -
        docker-compose stop mysql-mailcow watchdog-mailcow
        -docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && bash && exit 0"' mysql-mailcow
        -
        +

        docker-compose stop mysql-mailcow watchdog-mailcow +docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && bash && exit 0"' mysql-mailcow

        Sobald die SQL-Shell gestartet wurde, führen Sie mysql_upgrade aus und verlassen den Container:

        -
        mysql_upgrade
        -exit
        -
        +

        mysql_upgrade +exit


        @@ -2550,7 +2548,7 @@ exit - + diff --git a/de/troubleshooting/debug-reset_pw/index.html b/de/troubleshooting/debug-reset_pw/index.html index 4c02a0149..09dc1a510 100644 --- a/de/troubleshooting/debug-reset_pw/index.html +++ b/de/troubleshooting/debug-reset_pw/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -878,6 +878,26 @@ + + + + + +
      21. + + source mailcow.conf + + +
      22. + +
      23. + + docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} + + + - -
      24. - -
      25. +
      26. Zwei-Faktor-Authentifizierung entfernen @@ -935,6 +950,11 @@ +
      27. + + + + @@ -2491,6 +2511,26 @@ + + + + + +
      28. + + source mailcow.conf + + +
      29. + +
      30. + + docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} + + + - -
      31. - -
      32. +
      33. Zwei-Faktor-Authentifizierung entfernen @@ -2548,6 +2583,11 @@ +
      34. + + + + @@ -2568,22 +2608,19 @@ -

        Passwörter zurücksetzen (inkl. SQL)

        -

        mailcow Admin-Konto

        Setzt den mailcow Admin Account auf ein zufälliges Passwort zurück. Ältere mailcow: dockerisierte Installationen können das mailcow-reset-admin.sh Skript in ihrem mailcow Stammverzeichnis (mailcow_path) finden.

        -
        cd mailcow_pfad
        -./helper-scripts/mailcow-reset-admin.sh
        -
        +

        cd mailcow_pfad +./helper-scripts/mailcow-reset-admin.sh

        MySQL-Passwörter zurücksetzen

        Stoppen Sie den Stack, indem Sie docker-compose stop ausführen.

        Wenn die Container heruntergefahren sind, führen Sie diesen Befehl aus:

        -
        docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && mysql -hlocalhost -uroot && exit 0"' mysql-mailcow
        -
        +

        docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && mysql -hlocalhost -uroot && exit 0"' mysql-mailcow

        1. Datenbank-Name finden

        -
        # source mailcow.conf
        -# docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
        -MariaDB [(none)]> show databases;
        +

        ```

        +

        source mailcow.conf

        +

        docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}

        +

        MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ @@ -2593,49 +2630,47 @@ MariaDB [(none)]> show databases; | performance_schema | +--------------------+ 4 rows in set (0.00 sec) -

        +```

        2. Einen oder mehrere Benutzer zurücksetzen

        2.1 Maria DB < 10.4 (ältere mailcow-Installationen)

        Sowohl "password" als auch "authentication_string" existieren. Derzeit wird "password" verwendet, aber besser ist es, beide zu setzen.

        -
        MariaDB [(none)]> SELECT user FROM mysql.user;
        +

        ``` +MariaDB [(none)]> SELECT user FROM mysql.user; +--------------+ | user | +--------------+ | mailcow | <===== | root | +--------------+ -2 rows in set (0.00 sec) - +2 rows in set (0.00 sec)

        +

        MariaDB [(none)]> FLUSH PRIVILEGES; +MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('gotr00t'), password = PASSWORD('gotr00t') WHERE User = 'root'; +MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('mookuh'), password = PASSWORD('mookuh') WHERE User = 'mailcow' AND Host = '%'; MariaDB [(none)]> FLUSH PRIVILEGES; -MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('gotr00t'), password = PASSWORD('gotr00t') WHERE User = 'root'; -MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('mookuh'), password = PASSWORD('mookuh') WHERE User = 'mailcow' AND Host = '%'; -MariaDB [(none)]> FLUSH PRIVILEGES; -

        +```

        2.2 Maria DB >= 10.4 (aktuelle mailcows)

        -
        MariaDB [(none)]> SELECT user FROM mysql.user;
        +

        ``` +MariaDB [(none)]> SELECT user FROM mysql.user; +--------------+ | user | +--------------+ | mailcow | <===== | root | +--------------+ -2 rows in set (0.00 sec) - +2 rows in set (0.00 sec)

        +

        MariaDB [(none)]> FLUSH PRIVILEGES; +MariaDB [(none)]> ALTER USER 'mailcow'@'%' IDENTIFIED BY 'mookuh'; +MariaDB [(none)]> ALTER USER 'root'@'%' IDENTIFIED BY 'gotr00t'; MariaDB [(none)]> ALTER USER 'root'@'%' IDENTIFIED BY 'gotr00t'; +MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'gotr00t'; MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'gotr00t'; MariaDB [(none)]> FLUSH PRIVILEGES; -MariaDB [(none)]> ALTER USER 'mailcow'@'%' IDENTIFIED BY 'mookuh'; -MariaDB [(none)]> ALTER USER 'root'@'%' IDENTIFIED BY 'gotr00t'; MariaDB [(none)]> ALTER USER 'root'@'%' IDENTIFIED BY 'gotr00t'; -MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'gotr00t'; MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'gotr00t'; -MariaDB [(none)]> FLUSH PRIVILEGES; -

        +```

        Zwei-Faktor-Authentifizierung entfernen

        Für mailcow WebUI:

        Dies funktioniert ähnlich wie das Zurücksetzen eines MySQL-Passworts, jetzt machen wir es vom Host aus, ohne uns mit dem MySQL CLI zu verbinden:

        -
        Quelle mailcow.conf
        -docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='YOUR_USERNAME';"
        -
        +

        Quelle mailcow.conf +docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='YOUR_USERNAME';"

        Für SOGo:

        -
        docker-compose exec -u sogo sogo-mailcow sogo-tool user-preferences set defaults user@example.com SOGoGoogleAuthenticatorEnabled '{"SOGoGoogleAuthenticatorEnabled":0}'
        -
        +

        docker-compose exec -u sogo sogo-mailcow sogo-tool user-preferences set defaults user@example.com SOGoGoogleAuthenticatorEnabled '{"SOGoGoogleAuthenticatorEnabled":0}'


        @@ -2755,7 +2790,7 @@ docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e &qu - + diff --git a/de/troubleshooting/debug-reset_tls/index.html b/de/troubleshooting/debug-reset_tls/index.html index 892045790..9169d82da 100644 --- a/de/troubleshooting/debug-reset_tls/index.html +++ b/de/troubleshooting/debug-reset_tls/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2374,14 +2374,13 @@

        TLS-Zertifikate zurücksetzen

        Sollten Sie Probleme mit Ihrem Zertifikat, Schlüssel oder Let's Encrypt-Konto haben, versuchen Sie bitte, die TLS-Assets zurückzusetzen:

        -
        source mailcow.conf
        +

        source mailcow.conf docker-compose down rm -rf data/assets/ssl mkdir data/assets/ssl -openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes +openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes cp -n -d data/assets/ssl-example/*.pem data/assets/ssl/ -docker-compose up -d -

        +docker-compose up -d

        Dies wird mailcow stoppen, die benötigten Variablen beschaffen, ein selbstsigniertes Zertifikat erstellen und mailcow starten.

        Wenn Sie Let's Encrypt verwenden, sollten Sie vorsichtig sein, da Sie ein neues Konto und einen neuen Satz von Zertifikaten erstellen werden. Sie werden früher oder später auf ein Ratelimit stoßen.

        Bitte beachten Sie auch, dass frühere TLSA-Datensätze ungültig werden.

        @@ -2504,7 +2503,7 @@ docker-compose up -d - + diff --git a/de/troubleshooting/debug-rm_volumes/index.html b/de/troubleshooting/debug-rm_volumes/index.html index f5e7608be..2f74d686f 100644 --- a/de/troubleshooting/debug-rm_volumes/index.html +++ b/de/troubleshooting/debug-rm_volumes/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,8 +2376,7 @@

        Es kann sein, dass Sie einen Satz persistenter Daten entfernen wollen, um einen Konflikt zu lösen oder um neu zu beginnen.

        mailcowdockerized kann variieren und hängt von Ihrem Compose-Projektnamen ab (wenn er unverändert ist, ist mailcowdockerized der richtige Wert). Wenn Sie sich unsicher sind, führen Sie docker volume ls aus, um eine vollständige Liste zu erhalten.

        Löschen Sie ein einzelnes Volume:

        -
        docker volume rm mailcowdockerized_${VOLUME_NAME}
        -
        +

        docker volume rm mailcowdockerized_${VOLUME_NAME}

        • Entfernen Sie Volume mysql-vol-1, um alle MySQL-Daten zu entfernen.
        • Entfernen Sie Volume redis-vol-1 um alle Redis Daten zu entfernen.
        • @@ -2505,7 +2504,7 @@ - + diff --git a/de/troubleshooting/debug-rspamd_memory_leaks/index.html b/de/troubleshooting/debug-rspamd_memory_leaks/index.html index f904d8553..c17229bfc 100644 --- a/de/troubleshooting/debug-rspamd_memory_leaks/index.html +++ b/de/troubleshooting/debug-rspamd_memory_leaks/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,24 +2380,18 @@ -

          Fortgeschritten: Memory-Leaks in Rspamd finden

          -

          Eine kurze Anleitung, um einen schlecht funktionierenden Rspamd tiefgehend zu analysieren.

          -
          docker-compose exec rspamd-mailcow bash
          -
          -if ! grep -qi 'apt-stable-asan' /etc/apt/sources.list.d/rspamd.list; then
          -  sed -i 's/apt-stabil/apt-stabil-asan/i' /etc/apt/sources.list.d/rspamd.list
          -fi
          -
          -apt-get update ; apt-get upgrade rspamd
          -
          -nano /docker-entrypoint.sh
          -
          -# Fügen Sie vor "exec "$@"" die folgenden Zeilen ein:
          -
          -export G_SLICE=always-malloc
          -export ASAN_OPTIONS=new_delete_type_mismatch=0:detect_leaks=1:detect_odr_violation=0:log_path=/tmp/rspamd-asan:quarantine_size_mb=2048:malloc_context_size=8:fast_unwind_on_malloc=0
          -
          +

          ``` +docker-compose exec rspamd-mailcow bash

          +

          if ! grep -qi 'apt-stable-asan' /etc/apt/sources.list.d/rspamd.list; then + sed -i 's/apt-stabil/apt-stabil-asan/i' /etc/apt/sources.list.d/rspamd.list +fi

          +

          apt-get update ; apt-get upgrade rspamd

          +

          nano /docker-entrypoint.sh

          +

          Fügen Sie vor "exec "$@"" die folgenden Zeilen ein:

          +

          export G_SLICE=always-malloc +export ASAN_OPTIONS=new_delete_type_mismatch=0:detect_leaks=1:detect_odr_violation=0:log_path=/tmp/rspamd-asan:quarantine_size_mb=2048:malloc_context_size=8:fast_unwind_on_malloc=0

          +

          ```

          Starten Sie Rspamd neu: docker-compose restart rspamd-mailcow

          Ihr Speicherverbrauch wird stark ansteigen, er wird auch stetig wachsen, was nicht mit einem möglichen Memory Leak zusammenhängt, nach dem Sie suchen.

          Lassen Sie den Container für ein paar Minuten, Stunden oder Tage laufen (es sollte die Zeit sein, die Sie normalerweise warten, bis der Memory Leak "passiert") und starten Sie ihn neu: docker-compose restart rspamd-mailcow.

          @@ -2512,7 +2515,7 @@ export ASAN_OPTIONS=new_delete_type_mismatch=0:detect_leaks=1:detect_odr_violati - + diff --git a/de/troubleshooting/debug/index.html b/de/troubleshooting/debug/index.html index fa09bcbfb..2c04bbcee 100644 --- a/de/troubleshooting/debug/index.html +++ b/de/troubleshooting/debug/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2502,7 +2502,7 @@ - + diff --git a/en/backup_restore/b_n_r-accidental_deletion/index.html b/en/backup_restore/b_n_r-accidental_deletion/index.html index c21e7b756..86d0af69a 100644 --- a/en/backup_restore/b_n_r-accidental_deletion/index.html +++ b/en/backup_restore/b_n_r-accidental_deletion/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2456,9 +2456,8 @@

          To restore make sure you are actually restoring to the same mailcow it was deleted from or you use the same encryption keys in crypt-vol-1.

          Make sure the user you want to restore exists in your mailcow. Re-create them if they are missing.

          Copy the folders from /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/_garbage/[timestamp]_[domain_sanitized][user_sanitized] back to /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/[domain]/[user] and resync the folder and recalc the quota:

          -
          docker-compose exec dovecot-mailcow doveadm force-resync -u restoreme@example.net '*'
          -docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.net
          -
          +

          docker-compose exec dovecot-mailcow doveadm force-resync -u restoreme@example.net '*' +docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.net


          @@ -2578,7 +2577,7 @@ docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.ne - + diff --git a/en/backup_restore/b_n_r-backup/index.html b/en/backup_restore/b_n_r-backup/index.html index 7c69c17e2..e3d244f67 100644 --- a/en/backup_restore/b_n_r-backup/index.html +++ b/en/backup_restore/b_n_r-backup/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -961,6 +961,47 @@ +
        + + + + +
      35. + + Syntax: + + +
      36. + +
      37. + + ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days) + + +
      38. + +
      39. + + Backup all, delete backups older than 3 days + + +
      40. + +
      41. + + Backup vmail, crypt and mysql data, delete backups older than 30 days + + +
      42. + +
      43. + + Backup vmail + + + +
      44. + +
      45. + + !/bin/sh + + +
      46. + +
      47. + + Backup mailcow data + + +
      48. + +
      49. + + https://mailcow.github.io/mailcow-dockerized-docs/backup_restore/b_n_r-backup/ + + +
      50. + +
      51. + + run command + +
      52. @@ -978,6 +1047,13 @@ Backup strategy with rsync and mailcow backup script +
      53. + +
      54. + + If you want to, use the acl util to backup permissions of some/all folders/files: getfacl -Rn /path + +
      55. @@ -2439,6 +2515,47 @@ + + + + + +
      56. + + Syntax: + + +
      57. + +
      58. + + ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days) + + +
      59. + +
      60. + + Backup all, delete backups older than 3 days + + +
      61. + +
      62. + + Backup vmail, crypt and mysql data, delete backups older than 30 days + + +
      63. + +
      64. + + Backup vmail + + + +
      65. + +
      66. + + !/bin/sh + + +
      67. + +
      68. + + Backup mailcow data + + +
      69. + +
      70. + + https://mailcow.github.io/mailcow-dockerized-docs/backup_restore/b_n_r-backup/ + + +
      71. + +
      72. + + run command + +
      73. @@ -2456,6 +2601,13 @@ Backup strategy with rsync and mailcow backup script +
      74. + +
      75. + + If you want to, use the acl util to backup permissions of some/all folders/files: getfacl -Rn /path + +
      76. @@ -2482,65 +2634,57 @@

        Please do not copy this script to another location.

        To run a backup, write "backup" as first parameter and either one or more components to backup as following parameters. You can also use "all" as second parameter to backup all components. Append --delete-days n to delete backups older than n days.

        -
        # Syntax:
        -# ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days)
        -
        -# Backup all, delete backups older than 3 days
        -./helper-scripts/backup_and_restore.sh backup all --delete-days 3
        -
        -# Backup vmail, crypt and mysql data, delete backups older than 30 days
        -./helper-scripts/backup_and_restore.sh backup vmail crypt mysql --delete-days 30
        -
        -# Backup vmail
        -./helper-scripts/backup_and_restore.sh backup vmail
        -
        +

        ```

        +

        Syntax:

        +

        ./helper-scripts/backup_and_restore.sh backup (vmail|crypt|redis|rspamd|postfix|mysql|all|--delete-days)

        +

        Backup all, delete backups older than 3 days

        +

        ./helper-scripts/backup_and_restore.sh backup all --delete-days 3

        +

        Backup vmail, crypt and mysql data, delete backups older than 30 days

        +

        ./helper-scripts/backup_and_restore.sh backup vmail crypt mysql --delete-days 30

        +

        Backup vmail

        +

        ./helper-scripts/backup_and_restore.sh backup vmail

        +

        ```

        The script will ask you for a backup location. Inside of this location it will create folders in the format "mailcow_DATE". You should not rename those folders to not break the restore process.

        To run a backup unattended, define MAILCOW_BACKUP_LOCATION as environment variable before starting the script:

        -
        MAILCOW_BACKUP_LOCATION=/opt/backup /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all
        -
        +

        MAILCOW_BACKUP_LOCATION=/opt/backup /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all

        Cronjob

        You can run the backup script regularly via cronjob. Make sure BACKUP_LOCATION exists:

        -
        5 4 * * * cd /opt/mailcow-dockerized/; MAILCOW_BACKUP_LOCATION=/mnt/mailcow_backups /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3
        -
        +

        5 4 * * * cd /opt/mailcow-dockerized/; MAILCOW_BACKUP_LOCATION=/mnt/mailcow_backups /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3

        Per default cron sends the full result of each backup operation by email. If you want cron to only mail on error (non-zero exit code) you may want to use the following snippet. Pathes need to be modified according to your setup (this script is a user contribution).

        This following script may be placed in /etc/cron.daily/mailcow-backup - do not forget to mark it as executable via chmod +x:

        -
        #!/bin/sh
        -
        -# Backup mailcow data
        -# https://mailcow.github.io/mailcow-dockerized-docs/backup_restore/b_n_r-backup/
        -
        -set -e
        -
        -OUT="$(mktemp)"
        -export MAILCOW_BACKUP_LOCATION="/opt/backup"
        -SCRIPT="/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh"
        -PARAMETERS="backup all"
        -OPTIONS="--delete-days 30"
        -
        -# run command
        -set +e
        -"${SCRIPT}" ${PARAMETERS} ${OPTIONS} 2>&1 > "$OUT"
        -RESULT=$?
        -
        -if [ $RESULT -ne 0 ]
        +

        ```

        +

        !/bin/sh

        +

        Backup mailcow data

        +

        https://mailcow.github.io/mailcow-dockerized-docs/backup_restore/b_n_r-backup/

        +

        set -e

        +

        OUT="$(mktemp)" +export MAILCOW_BACKUP_LOCATION="/opt/backup" +SCRIPT="/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh" +PARAMETERS="backup all" +OPTIONS="--delete-days 30"

        +

        run command

        +

        set +e +"${SCRIPT}" ${PARAMETERS} ${OPTIONS} 2>&1 > "$OUT" +RESULT=$?

        +

        if [ $RESULT -ne 0 ] then - echo "${SCRIPT} ${PARAMETERS} ${OPTIONS} encounters an error:" - echo "RESULT=$RESULT" - echo "STDOUT / STDERR:" - cat "$OUT" + echo "${SCRIPT} ${PARAMETERS} ${OPTIONS} encounters an error:" + echo "RESULT=$RESULT" + echo "STDOUT / STDERR:" + cat "$OUT" fi -

        +```

        Backup strategy with rsync and mailcow backup script

        Create the destination directory for mailcows helper script: -

        mkdir -p /external_share/backups/backup_script
        -

        +mkdir -p /external_share/backups/backup_script

        Create cronjobs: -

        25 1 * * * rsync -aH --delete /opt/mailcow-dockerized /external_share/backups/mailcow-dockerized
        +```
        +25 1 * * * rsync -aH --delete /opt/mailcow-dockerized /external_share/backups/mailcow-dockerized
         40 2 * * * rsync -aH --delete /var/lib/docker/volumes /external_share/backups/var_lib_docker_volumes
        -5 4 * * * cd /opt/mailcow-dockerized/; BACKUP_LOCATION=/external_share/backups/backup_script /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3
        -# If you want to, use the acl util to backup permissions of some/all folders/files: getfacl -Rn /path
        -

        +5 4 * * * cd /opt/mailcow-dockerized/; BACKUP_LOCATION=/external_share/backups/backup_script /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3

        +

        If you want to, use the acl util to backup permissions of some/all folders/files: getfacl -Rn /path

        +

        ```

        On the destination (in this case /external_share/backups) you may want to have snapshot capabilities (ZFS, Btrfs etc.). Snapshot daily and keep for n days for a consistent backup. Do not rsync to a Samba share, you need to keep the correct permissions!

        To restore you'd simply need to run rsync the other way round and restart Docker to re-read the volumes. Run docker-compose pull and docker-compose up -d.

        @@ -2665,7 +2809,7 @@ In case of a corrupted database you'd need to use the helper script to restore t - + diff --git a/en/backup_restore/b_n_r-backup_restore-maildir/index.html b/en/backup_restore/b_n_r-backup_restore-maildir/index.html index e2b701611..63451e3f2 100644 --- a/en/backup_restore/b_n_r-backup_restore-maildir/index.html +++ b/en/backup_restore/b_n_r-backup_restore-maildir/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2440,15 +2440,13 @@

        Backup

        This line backups the vmail directory to a file backup_vmail.tar.gz in the mailcow root directory: -

        cd /path/to/mailcow-dockerized
        -docker run --rm -i -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar cvfz /backup/backup_vmail.tar.gz /vmail
        -

        +cd /path/to/mailcow-dockerized +docker run --rm -i -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar cvfz /backup/backup_vmail.tar.gz /vmail

        You can change the path by adjusting ${PWD} (which equals to the current directory) to any path you have write-access to. Set the filename backup_vmail.tar.gz to any custom name, but leave the path as it is. Example: [...] tar cvfz /backup/my_own_filename_.tar.gz

        Restore

        -
        cd /path/to/mailcow-dockerized
        -docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar xvfz /backup/backup_vmail.tar.gz
        -
        +

        cd /path/to/mailcow-dockerized +docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/var/vmail" }}{{ .Name }}{{ end }}{{ end }}' $(docker-compose ps -q dovecot-mailcow)):/vmail -v ${PWD}:/backup debian:stretch-slim tar xvfz /backup/backup_vmail.tar.gz


        @@ -2568,7 +2566,7 @@ docker run --rm -it -v $(docker inspect --format '{{ range .Mounts }}{{ if e - + diff --git a/en/backup_restore/b_n_r-backup_restore-mysql/index.html b/en/backup_restore/b_n_r-backup_restore-mysql/index.html index a453371df..486ccb2d4 100644 --- a/en/backup_restore/b_n_r-backup_restore-mysql/index.html +++ b/en/backup_restore/b_n_r-backup_restore-mysql/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2439,20 +2439,18 @@

        MySQL (mysqldump)

        Backup

        -
        cd /path/to/mailcow-dockerized
        +

        cd /path/to/mailcow-dockerized source mailcow.conf -DATE=$(date +"%Y%m%d_%H%M%S") -docker-compose exec -T mysql-mailcow mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql -

        +DATE=$(date +"%Y%m%d_%H%M%S") +docker-compose exec -T mysql-mailcow mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql

        Restore

        Warning

        You should redirect the SQL dump without docker-compose to prevent parsing errors.

        -
        cd /path/to/mailcow-dockerized
        +

        cd /path/to/mailcow-dockerized source mailcow.conf -docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < backup_file.sql -

        +docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < backup_file.sql


        @@ -2572,7 +2570,7 @@ docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPAS - + diff --git a/en/backup_restore/b_n_r-coldstandby/index.html b/en/backup_restore/b_n_r-coldstandby/index.html index 428542cef..34b9088f4 100644 --- a/en/backup_restore/b_n_r-coldstandby/index.html +++ b/en/backup_restore/b_n_r-coldstandby/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2487,10 +2487,9 @@

        You will need a SSH-enabled destination and a keyfile to connect to said destination. The key should not be protected by a password for the script to work unattended.

        In your mailcow base directory, e.g. /opt/mailcow-dockerized you will find a file create_cold_standby.sh.

        Edit this file and change the exported variables:

        -
        export REMOTE_SSH_KEY=/path/to/keyfile
        +

        export REMOTE_SSH_KEY=/path/to/keyfile export REMOTE_SSH_PORT=22 -export REMOTE_SSH_HOST=mailcow-backup.host.name -

        +export REMOTE_SSH_HOST=mailcow-backup.host.name

        The key must be owned and readable by root only.

        Both the source and destination require rsync >= v3.1.0. The destination must have Docker and docker-compose v1 available.

        @@ -2498,28 +2497,23 @@ The destination must have Docker and docker-compose v1 availabl

        You may want to test the connection by running ssh mailcow-backup.host.name -p22 -i /path/to/keyfile.

        Backup and refresh the cold-standby

        Run the first backup, this may take a while depending on the connection:

        -
        bash /opt/mailcow-dockerized/create_cold_standby.sh
        -
        +

        bash /opt/mailcow-dockerized/create_cold_standby.sh

        That was easy, wasn't it?

        Updating your cold-standby is just as easy:

        -
        bash /opt/mailcow-dockerized/create_cold_standby.sh
        -
        +

        bash /opt/mailcow-dockerized/create_cold_standby.sh

        It's the same command.

        Automated backups with cron

        First make sure that the cron service is enabled and running:

        -
        systemctl enable cron.service && systemctl start cron.service
        -
        +

        systemctl enable cron.service && systemctl start cron.service

        To automate the backups to the cold-standby server you can use a cron job. To edit the cron jobs for the root user run:

        -
        crontab -e
        -
        +

        crontab -e

        Add the following lines to synchronize the cold standby server daily at 03:00. In this example errors of the last execution are logged into a file.

        -
        PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
        -
        -0 3 * * * bash /opt/mailcow-dockerized/create_cold_standby.sh 2> /var/log/mailcow-coldstandby-sync.log
        -
        +

        ``` +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

        +

        0 3 * * * bash /opt/mailcow-dockerized/create_cold_standby.sh 2> /var/log/mailcow-coldstandby-sync.log +```

        If saved correctly, the cron job should be shown by typing:

        -
        crontab -l
        -
        +

        crontab -l


        @@ -2639,7 +2633,7 @@ The destination must have Docker and docker-compose v1 availabl - + diff --git a/en/backup_restore/b_n_r-restore/index.html b/en/backup_restore/b_n_r-restore/index.html index bdf07567f..344463692 100644 --- a/en/backup_restore/b_n_r-restore/index.html +++ b/en/backup_restore/b_n_r-restore/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -965,6 +965,20 @@ Restore + + +
      77. + + Syntax: + + +
      78. + +
      79. + + ./helper-scripts/backup_and_restore.sh restore + +
      80. @@ -2402,6 +2416,20 @@ Restore + + +
      81. + + Syntax: + + +
      82. + +
      83. + + ./helper-scripts/backup_and_restore.sh restore + +
      84. @@ -2422,14 +2450,13 @@ -

        Restore

        -

        Restore

        Please do not copy this script to another location.

        To run a restore, start mailcow, use the script with "restore" as first parameter.

        -
        # Syntax:
        -# ./helper-scripts/backup_and_restore.sh restore
        -
        +

        ```

        +

        Syntax:

        +

        ./helper-scripts/backup_and_restore.sh restore

        +

        ```

        The script will ask you for a backup location containing the mailcow_DATE folders.


        @@ -2550,7 +2577,7 @@ - + diff --git a/en/client/client-android/index.html b/en/client/client-android/index.html index d832159b2..cd5247bbf 100644 --- a/en/client/client-android/index.html +++ b/en/client/client-android/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2499,7 +2499,7 @@ - + diff --git a/en/client/client-apple/index.html b/en/client/client-apple/index.html index 9f79bb395..4f9cb4b77 100644 --- a/en/client/client-apple/index.html +++ b/en/client/client-apple/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2607,7 +2607,7 @@ - + diff --git a/en/client/client-emclient/index.html b/en/client/client-emclient/index.html index 24b89c458..4e3a6193d 100644 --- a/en/client/client-emclient/index.html +++ b/en/client/client-emclient/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2501,7 +2501,7 @@ - + diff --git a/en/client/client-kontact/index.html b/en/client/client-kontact/index.html index fb26bab2b..173d3d06a 100644 --- a/en/client/client-kontact/index.html +++ b/en/client/client-kontact/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2509,7 +2509,7 @@ - + diff --git a/en/client/client-manual/index.html b/en/client/client-manual/index.html index 66bcbd0e7..b55e63961 100644 --- a/en/client/client-manual/index.html +++ b/en/client/client-manual/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2613,7 +2613,7 @@ - + diff --git a/en/client/client-outlook/index.html b/en/client/client-outlook/index.html index 8dd9b385f..32ab5508d 100644 --- a/en/client/client-outlook/index.html +++ b/en/client/client-outlook/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2639,7 +2639,7 @@ - + diff --git a/en/client/client-thunderbird/index.html b/en/client/client-thunderbird/index.html index 5c19b82a5..1d641d8e8 100644 --- a/en/client/client-thunderbird/index.html +++ b/en/client/client-thunderbird/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2518,7 +2518,7 @@ - + diff --git a/en/client/client-windows/index.html b/en/client/client-windows/index.html index f6798e185..59e35fa8f 100644 --- a/en/client/client-windows/index.html +++ b/en/client/client-windows/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2502,7 +2502,7 @@ - + diff --git a/en/client/client/index.html b/en/client/client/index.html index 478aac4c3..d0cb228cc 100644 --- a/en/client/client/index.html +++ b/en/client/client/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2516,7 +2516,7 @@ Since you accessed this page after logging into your mailcow server, all of the - + diff --git a/en/i_u_m/i_u_m_deinstall/index.html b/en/i_u_m/i_u_m_deinstall/index.html index 185c866c8..e131059d6 100644 --- a/en/i_u_m/i_u_m_deinstall/index.html +++ b/en/i_u_m/i_u_m_deinstall/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2374,8 +2374,7 @@

        Deinstallation

        To remove mailcow: dockerized with all it's volumes, images and containers do:

        -
        docker-compose down -v --rmi all --remove-orphans
        -
        +

        docker-compose down -v --rmi all --remove-orphans

        Info

          @@ -2504,7 +2503,7 @@ - + diff --git a/en/i_u_m/i_u_m_install/index.html b/en/i_u_m/i_u_m_install/index.html index 2b35b1fee..0b401df57 100644 --- a/en/i_u_m/i_u_m_install/index.html +++ b/en/i_u_m/i_u_m_install/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,66 +2380,58 @@ -

          Installation

          -

          You need Docker (a version >= 20.10.2 is required) and Docker Compose (a version <= 2.0 is required).

          1. Learn how to install Docker and Docker Compose.

          Quick installation for most operation systems:

            -
          • -

            Docker -

            curl -sSL https://get.docker.com/ | CHANNEL=stable sh
            -# After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS 7)
            -systemctl enable --now docker
            -

            -
          • -
          • -

            Docker-Compose

            -
          • +
          • Docker +``` +curl -sSL https://get.docker.com/ | CHANNEL=stable sh
          • +
          +

          After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS 7)

          +

          systemctl enable --now docker +```

          +
            +
          • Docker-Compose

          Warning

          mailcow requires the latest version of docker-compose v1. It is highly recommended to use the commands below to install docker-compose. Package managers (e.g. apt, yum) likely won't give you the correct version. Note: This command downloads docker-compose from the official Docker Github repository and is a safe method. The snippet will determine the latest supported version by mailcow. In almost all cases this is the latest version available (exceptions are broken releases or major changes not yet supported by mailcow).

          -
          curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose
          -chmod +x /usr/local/bin/docker-compose
          -
          +

          curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose

          Please use the latest Docker engine available and do not use the engine that ships with your distros repository.

          1.1. On SELinux enabled systems, e.g. CentOS 7:

          • Check if "container-selinux" package is present on your system:
          -
          rpm -qa | grep container-selinux
          -
          +

          rpm -qa | grep container-selinux

          If the above command returns an empty or no output, you should install it via your package manager.

          • Check if docker has SELinux support enabled:
          -
          docker info | grep selinux
          -
          +

          docker info | grep selinux

          If the above command returns an empty or no output, create or edit /etc/docker/daemon.json and add "selinux-enabled": true. Example file content:

          -
          {
          -  "selinux-enabled": true
          -}
          -
          +

          { + "selinux-enabled": true +}

          Restart the docker daemon and verify SELinux is now enabled.

          This step is required to make sure mailcows volumes are properly labeled as declared in the compose file. If you are interested in how this works, you can check out the readme of https://github.com/containers/container-selinux which links to a lot of useful information on that topic.

          2. Clone the master branch of the repository, make sure your umask equals 0022. Please clone the repository as root user and also control the stack as root. We will modify attributes - if necessary - while bootstrapping the containers automatically and make sure everything is secured. The update.sh script must therefore also be run as root. It might be necessary to change ownership and other attributes of files you will otherwise not have access to. We drop permissions for every exposed application and will not run an exposed service as root! Controlling the Docker daemon as non-root user does not give you additional security. The unprivileged user will spawn the containers as root likewise. The behaviour of the stack is identical.

          -
          $ su
          -# umask
          -0022 # <- Verify it is 0022
          -# cd /opt
          -# git clone https://github.com/mailcow/mailcow-dockerized
          -# cd mailcow-dockerized
          -
          +

          ``` +$ su

          +

          umask

          +

          0022 # <- Verify it is 0022

          +

          cd /opt

          +

          git clone https://github.com/mailcow/mailcow-dockerized

          +

          cd mailcow-dockerized

          +

          ```

          3. Generate a configuration file. Use a FQDN (host.domain.tld) as hostname when asked. -

          ./generate_config.sh
          -

          +./generate_config.sh

          4. Change configuration if you want or need to. -

          nano mailcow.conf
          -
          +nano mailcow.conf If you plan to use a reverse proxy, you can, for example, bind HTTPS to 127.0.0.1 on port 8443 and HTTP to 127.0.0.1 on port 8080.

          You may need to stop an existing pre-installed MTA which blocks port 25/tcp. See this chapter to learn how to reconfigure Postfix to run besides mailcow after a successful installation.

          Some updates modify mailcow.conf and add new parameters. It is hard to keep track of them in the documentation. Please check their description and, if unsure, ask at the known channels for advise.

          @@ -2438,20 +2439,18 @@ If you plan to use a reverse proxy, you can, for example, bind HTTPS to 127.0.0.

          Whenever you run into trouble and strange phenomena, please check your MTU.

          Edit docker-compose.yml and change the network settings according to your MTU. Add the new driver_opts parameter like this: -

          networks:
          +networks:
             mailcow-network:
               ...
               driver_opts:
                 com.docker.network.driver.mtu: 1450
          -    ...
          -

          + ...

          4.2. Users without an IPv6 enabled network on their host system:

          Enable IPv6. Finally.

          If you do not have an IPv6 enabled network on your host and you don't care for a better internet (thehe), it is recommended to disable IPv6 for the mailcow network to prevent unforeseen issues.

          5. Pull the images and run the compose file. The parameter -d will start mailcow: dockerized detached: -

          docker-compose pull
          -docker-compose up -d
          -

          +docker-compose pull +docker-compose up -d

          Done!

          You can now access https://${MAILCOW_HOSTNAME} with the default credentials admin + password moohoo.

          @@ -2579,7 +2578,7 @@ docker-compose up -d - + diff --git a/en/i_u_m/i_u_m_migration/index.html b/en/i_u_m/i_u_m_migration/index.html index 1944bb8b0..9a3d59fb0 100644 --- a/en/i_u_m/i_u_m_migration/index.html +++ b/en/i_u_m/i_u_m_migration/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,8 +2380,6 @@ -

          Migration

          -

          Warning

          This guide assumes you intend to migrate an existing mailcow server (source) over to a brand new, empty server (target). It takes no care about preserving any existing data on your target server and will erase anything within /var/lib/docker/volumes and thus any Docker volumes you may have already set up.

          @@ -2385,45 +2392,37 @@ Install
          Docker and Docker Compose on your new server.

          Quick installation for most operation systems:

            -
          • -

            Docker -

            curl -sSL https://get.docker.com/ | CHANNEL=stable sh
            -# After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS 7)
            -systemctl enable docker.service
            -

            -
          • -
          • -

            docker-compose -

            curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose
            -chmod +x /usr/local/bin/docker-compose
            -

            -
          • +
          • Docker +``` +curl -sSL https://get.docker.com/ | CHANNEL=stable sh
          • +
          +

          After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS 7)

          +

          systemctl enable docker.service +```

          +
            +
          • docker-compose +curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose

          Please use the latest Docker engine available and do not use the engine that ships with your distros repository.

          2. Stop Docker and assure Docker has stopped: -

          systemctl stop docker.service
          -systemctl status docker.service
          -

          +systemctl stop docker.service +systemctl status docker.service

          3. Run the following commands on the source machine (take care of adding the trailing slashes in the first path parameter as shown below!) - WARNING: This command will erase anything that may already exist under /var/lib/docker/volumes on the target machine: -

          rsync -aHhP --numeric-ids --delete /opt/mailcow-dockerized/ root@target-machine.example.com:/opt/mailcow-dockerized
          -rsync -aHhP --numeric-ids --delete /var/lib/docker/volumes/ root@target-machine.example.com:/var/lib/docker/volumes
          -

          +rsync -aHhP --numeric-ids --delete /opt/mailcow-dockerized/ root@target-machine.example.com:/opt/mailcow-dockerized +rsync -aHhP --numeric-ids --delete /var/lib/docker/volumes/ root@target-machine.example.com:/var/lib/docker/volumes

          4. Shut down mailcow and stop Docker on the source machine. -

          cd /opt/mailcow-dockerized
          +cd /opt/mailcow-dockerized
           docker-compose down
          -systemctl stop docker.service
          -

          +systemctl stop docker.service

          5. Repeat step 3 with the same commands. This will be much quicker than the first time.

          6. Switch over to the target machine and start Docker. -

          systemctl start docker.service
          -

          +systemctl start docker.service

          7. Now pull the mailcow Docker images on the target machine. -

          cd /opt/mailcow-dockerized
          -docker-compose pull
          -

          +cd /opt/mailcow-dockerized +docker-compose pull

          8. Start the whole mailcow stack and everything should be done! -

          docker-compose up -d
          -

          +docker-compose up -d

          9. Finally, change your DNS settings to point to the target server.


          @@ -2544,7 +2543,7 @@ docker-compose pull - + diff --git a/en/i_u_m/i_u_m_update/index.html b/en/i_u_m/i_u_m_update/index.html index 2f31e84af..79e5eda45 100644 --- a/en/i_u_m/i_u_m_update/index.html +++ b/en/i_u_m/i_u_m_update/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -419,6 +419,82 @@ +
        + + + + +
      85. + + Options can be combined + + +
      86. + +
      87. + + - Check for updates and show changes + + +
      88. + +
      89. + + Do not try to update docker-compose, make sure to use the latest docker-compose available + + +
      90. + +
      91. + + - Do not start mailcow after applying an update + + +
      92. + +
      93. + + - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine) + + +
      94. + +
      95. + + - Force update (unattended, but unsupported, use at own risk) + + +
      96. + +
      97. + + - Run garbage collector to cleanup old image tags and exit + + +
      98. + +
      99. + + - Update with merge strategy option "ours" instead of "theirs" + + +
      100. + +
      101. + + This will solve conflicts when merging in favor for your local changes and should be avoided. Local changes will always be kept, unless we changed file XY, too. + + +
      102. + +
      103. + + - Don't update, but prefetch images and exit + + + + +
      104. + +
      105. + + Replace commit ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab by your ID + + + - -
      106. - -
      107. +
      108. Update Cycle +
      109. + + + + @@ -2451,6 +2540,82 @@ + + + + + +
      110. + + Options can be combined + + +
      111. + +
      112. + + - Check for updates and show changes + + +
      113. + +
      114. + + Do not try to update docker-compose, make sure to use the latest docker-compose available + + +
      115. + +
      116. + + - Do not start mailcow after applying an update + + +
      117. + +
      118. + + - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine) + + +
      119. + +
      120. + + - Force update (unattended, but unsupported, use at own risk) + + +
      121. + +
      122. + + - Run garbage collector to cleanup old image tags and exit + + +
      123. + +
      124. + + - Update with merge strategy option "ours" instead of "theirs" + + +
      125. + +
      126. + + This will solve conflicts when merging in favor for your local changes and should be avoided. Local changes will always be kept, unless we changed file XY, too. + + +
      127. + +
      128. + + - Don't update, but prefetch images and exit + + + + +
      129. + +
      130. + + Replace commit ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab by your ID + + + - -
      131. - -
      132. +
      133. Update Cycle +
      134. + + + + @@ -2502,60 +2680,50 @@ -

        Update

        -

        Automatic update

        An update script in your mailcow-dockerized directory will take care of updates.

        But use it with caution! If you think you made a lot of changes to the mailcow code, you should use the manual update guide below.

        Run the update script: -

        ./update.sh
        -

        +./update.sh

        If it needs to, it will ask you how you wish to proceed. Merge errors will be reported. Some minor conflicts will be auto-corrected (in favour for the mailcow: dockerized repository code).

        Options

        -
        # Options can be combined
        -
        -# - Check for updates and show changes
        -./update.sh --check
        -
        -# Do not try to update docker-compose, **make sure to use the latest docker-compose available**
        -./update.sh --no-update-compose
        -
        -# - Do not start mailcow after applying an update
        -./update.sh --skip-start
        -
        -# - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine)
        -./update.sh --skip-ping-check
        -
        -# - Force update (unattended, but unsupported, use at own risk)
        -./update.sh --force
        -
        -# - Run garbage collector to cleanup old image tags and exit
        -./update.sh --gc
        -
        -# - Update with merge strategy option "ours" instead of "theirs"
        -#   This will **solve conflicts** when merging in favor for your local changes and should be avoided. Local changes will always be kept, unless we changed file XY, too.
        -./update.sh --ours
        -
        -# - Don't update, but prefetch images and exit
        -./update.sh --prefetch
        -
        +

        ```

        +

        Options can be combined

        +

        - Check for updates and show changes

        +

        ./update.sh --check

        +

        Do not try to update docker-compose, make sure to use the latest docker-compose available

        +

        ./update.sh --no-update-compose

        +

        - Do not start mailcow after applying an update

        +

        ./update.sh --skip-start

        +

        - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine)

        +

        ./update.sh --skip-ping-check

        +

        - Force update (unattended, but unsupported, use at own risk)

        +

        ./update.sh --force

        +

        - Run garbage collector to cleanup old image tags and exit

        +

        ./update.sh --gc

        +

        - Update with merge strategy option "ours" instead of "theirs"

        +

        This will solve conflicts when merging in favor for your local changes and should be avoided. Local changes will always be kept, unless we changed file XY, too.

        +

        ./update.sh --ours

        +

        - Don't update, but prefetch images and exit

        +

        ./update.sh --prefetch +```

        I forgot what I changed before running update.sh

        See git log --pretty=oneline | grep -i "before update", you will have an output similar to this:

        -
        22cd00b5e28893ef9ddef3c2b5436453cc5223ab Before update on 2020-09-28_19_25_45
        -dacd4fb9b51e9e1c8a37d84485b92ffaf6c59353 Before update on 2020-08-07_13_31_31
        -
        +

        22cd00b5e28893ef9ddef3c2b5436453cc5223ab Before update on 2020-09-28_19_25_45 +dacd4fb9b51e9e1c8a37d84485b92ffaf6c59353 Before update on 2020-08-07_13_31_31

        Run git diff 22cd00b5e28893ef9ddef3c2b5436453cc5223ab to see what changed.

        Can I roll back?

        Yes.

        See the topic above, instead of a diff, you run checkout:

        -
        docker-compose down
        -# Replace commit ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab by your ID
        -git checkout 22cd00b5e28893ef9ddef3c2b5436453cc5223ab
        +

        ``` +docker-compose down

        +

        Replace commit ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab by your ID

        +

        git checkout 22cd00b5e28893ef9ddef3c2b5436453cc5223ab docker-compose pull docker-compose up -d -

        +```

        Hooks

        You can hook into the update mechanism by adding scripts called pre_commit_hook.sh and post_commit_hook.sh to your mailcows root directory. See this for more details.

        Update Cycle

        @@ -2683,7 +2851,7 @@ docker-compose up -d - + diff --git a/en/index.html b/en/index.html index 48d194784..a7508b7bb 100644 --- a/en/index.html +++ b/en/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2706,7 +2706,7 @@ Each container represents a single application.

        - + diff --git a/en/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html b/en/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html index 1d69cd5b3..d6c000f92 100644 --- a/en/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html +++ b/en/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2494,21 +2494,20 @@
      135. You will need to get your_id from one of the download links, they are individual for every user
      136. Add to data/conf/clamav/freshclam.conf with replaced your_id part: -

        DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfo.hdb
        +DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfo.hdb
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfo.ign2
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/javascript.ndb
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/spam_marketing.ndb
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfohtml.hdb
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfoascii.hdb
        -DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfopdf.hdb
        -

        +DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfopdf.hdb

      137. For free SecuriteInfo databases, download speed is limited to 300 kB/s. In data/conf/clamav/freshclam.conf, increase the default ReceiveTimeout 20 value to ReceiveTimeout 90 (time in seconds), otherwise some of the database downloads could fail because of their size.

      138. Adjust data/conf/clamav/clamd.conf to align with next settings: -

        DetectPUA yes
        +DetectPUA yes
         ExcludePUA PUA.Win.Packer
         ExcludePUA PUA.Win.Trojan.Packed
         ExcludePUA PUA.Win.Trojan.Molebox
        @@ -2520,12 +2519,11 @@ MaxRecursion 40
         MaxEmbeddedPE 100M
         MaxHTMLNormalize 50M
         MaxScriptNormalize 50M
        -MaxZipTypeRcg 50M
        -

        +MaxZipTypeRcg 50M

      139. Restart ClamAV container: -
        docker-compose restart clamd-mailcow
        -
      140. +bash +docker-compose restart clamd-mailcow

      Please note:

        @@ -2537,14 +2535,13 @@ MaxZipTypeRcg 50M

        Enable InterServer databases

        1. Add to data/conf/clamav/freshclam.conf: -
          DatabaseCustomURL http://sigs.interserver.net/interserver256.hdb
          +DatabaseCustomURL http://sigs.interserver.net/interserver256.hdb
           DatabaseCustomURL http://sigs.interserver.net/interservertopline.db
           DatabaseCustomURL http://sigs.interserver.net/shell.ldb
          -DatabaseCustomURL http://sigs.interserver.net/whitelist.fp
          -
        2. +DatabaseCustomURL http://sigs.interserver.net/whitelist.fp
        3. Restart ClamAV container: -
          docker-compose restart clamd-mailcow
          -
        4. +bash +docker-compose restart clamd-mailcow

        @@ -2665,7 +2662,7 @@ DatabaseCustomURL http://sigs.interserver.net/whitelist.fp - + diff --git a/en/manual-guides/ClamAV/u_e-clamav-whitelist/index.html b/en/manual-guides/ClamAV/u_e-clamav-whitelist/index.html index 5c459a5a9..7d01b54cb 100644 --- a/en/manual-guides/ClamAV/u_e-clamav-whitelist/index.html +++ b/en/manual-guides/ClamAV/u_e-clamav-whitelist/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1870,6 +1870,13 @@ Whitelist specific ClamAV signatures + + +
      • + + docker-compose exec redis-mailcow /bin/sh + +
      @@ -2402,6 +2409,13 @@ Whitelist specific ClamAV signatures + + +
    • + + docker-compose exec redis-mailcow /bin/sh + +
    • @@ -2422,26 +2436,25 @@ -

      Whitelist

      -

      Whitelist specific ClamAV signatures

      You may find that legitimate (clean) mail is being blocked by ClamAV (Rspamd will flag the mail with VIRUS_FOUND). For instance, interactive PDF form attachments are blocked by default because the embedded Javascript code may be used for nefarious purposes. Confirm by looking at the clamd logs, e.g.:

      -
      docker-compose logs clamd-mailcow | grep "FOUND"
      -
      +

      bash +docker-compose logs clamd-mailcow | grep "FOUND"

      This line confirms that such was identified:

      -
      clamd-mailcow_1      | Sat Sep 28 07:43:24 2019 -> instream(local): PUA.Pdf.Trojan.EmbeddedJavaScript-1(e887d2ac324ce90750768b86b63d0749:363325) FOUND
      -
      +

      text +clamd-mailcow_1 | Sat Sep 28 07:43:24 2019 -> instream(local): PUA.Pdf.Trojan.EmbeddedJavaScript-1(e887d2ac324ce90750768b86b63d0749:363325) FOUND

      To whitelist this particular signature (and enable sending this type of file attached), add it to the ClamAV signature whitelist file:

      -
      echo 'PUA.Pdf.Trojan.EmbeddedJavaScript-1' >> data/conf/clamav/whitelist.ign2
      -
      +

      bash +echo 'PUA.Pdf.Trojan.EmbeddedJavaScript-1' >> data/conf/clamav/whitelist.ign2

      Then restart the clamd-mailcow service container in the mailcow UI or using docker-compose:

      -
      docker-compose restart clamd-mailcow
      -
      +

      bash +docker-compose restart clamd-mailcow

      Cleanup cached ClamAV results in Redis:

      -
      # docker-compose exec redis-mailcow  /bin/sh
      -/data # redis-cli KEYS rs_cl* | xargs redis-cli DEL
      +

      ```

      +

      docker-compose exec redis-mailcow /bin/sh

      +

      /data # redis-cli KEYS rs_cl* | xargs redis-cli DEL /data # exit -

      +```


      @@ -2561,7 +2574,7 @@ - + diff --git a/en/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html b/en/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html index cd122db21..358110006 100644 --- a/en/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html +++ b/en/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,14 +2376,11 @@

      Customize Dockerfiles

      You need to copy the override file with corresponding build tags to the mailcow: dockerized root folder (i.e. /opt/mailcow-dockerized):

      -
      cp helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml docker-compose.override.yml
      -
      +

      cp helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml docker-compose.override.yml

      Make your changes in data/Dockerfiles/$service and build the image locally:

      -
      docker build data/Dockerfiles/service -t mailcow/$service
      -
      +

      docker build data/Dockerfiles/service -t mailcow/$service

      Now auto-recreate modified containers:

      -
      docker-compose up -d
      -
      +

      docker-compose up -d


      @@ -2503,7 +2500,7 @@ - + diff --git a/en/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html b/en/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html index eedad2f54..1cf382dd3 100644 --- a/en/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html +++ b/en/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,8 +2376,7 @@

      Docker Compose Bash Completion

      To get some sexy bash completion inside your containers simply execute the following:

      -
      curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
      -
      +

      curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose


      @@ -2497,7 +2496,7 @@ - + diff --git a/en/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html b/en/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html index d61373828..dc6cc989e 100644 --- a/en/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html +++ b/en/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,8 +2377,7 @@

      On August the 17th, we disabled the possibility to share with "any" or "all authenticated users" by default.

      This function can be re-enabled by setting ACL_ANYONE to allow in mailcow.conf:

      -
      ACL_ANYONE=allow
      -
      +

      ACL_ANYONE=allow

      Apply the changes by running docker-compose up -d.


      @@ -2499,7 +2498,7 @@ - + diff --git a/en/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html b/en/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html index 5a2173c8b..cd0776a0e 100644 --- a/en/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html +++ b/en/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2496,7 +2496,7 @@ - + diff --git a/en/manual-guides/Dovecot/u_e-dovecot-expunge/index.html b/en/manual-guides/Dovecot/u_e-dovecot-expunge/index.html index 81bae3e17..3a058865a 100644 --- a/en/manual-guides/Dovecot/u_e-dovecot-expunge/index.html +++ b/en/manual-guides/Dovecot/u_e-dovecot-expunge/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1592,6 +1592,33 @@ + + + + + +
    • + + !/bin/bash + + +
    • + +
    • + + Path to mailcow-dockerized, e.g. /opt/mailcow-dockerized + + +
    • + +
    • + + Execute everyday at 04:00 A.M. + + + + +
    • + +
    • + + !/bin/bash + + +
    • + +
    • + + Path to mailcow-dockerized, e.g. /opt/mailcow-dockerized + + +
    • + +
    • + + Execute everyday at 04:00 A.M. + + + + +
    • + +
    • + + single user + + +
    • + +
    • + + all users + + +
    • + +
    • + + single user + + +
    • + +
    • + + all users, but obviously slower and more dangerous + + + + +
    • + +
    • + + single user + + +
    • + +
    • + + all users + + +
    • + +
    • + + single user + + +
    • + +
    • + + all users, but obviously slower and more dangerous + + +
    • @@ -2373,36 +2382,34 @@ -

      Mail crypt

      -

      Mails are stored compressed (lz4) and encrypted. The key pair can be found in crypt-vol-1.

      If you want to decode/encode existing maildir files, you can use the following script at your own risk:

      Enter Dovecot by running docker-compose exec dovecot-mailcow /bin/bash in the mailcow-dockerized location.

      -
      # Decrypt /var/vmail
      -find /var/vmail/ -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do
      -if [[ $(head -c7 "$file") == "CRYPTED" ]]; then
      +

      ```

      +

      Decrypt /var/vmail

      +

      find /var/vmail/ -type f -regextype egrep -regex '.S=.W=.*' | while read -r file; do +if [[ $(head -c7 "$file") == "CRYPTED" ]]; then doveadm fs get compress lz4:0:crypt:private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ - "$file" > "/tmp/$(basename "$file")" - if [[ -s "/tmp/$(basename "$file")" ]]; then - chmod 600 "/tmp/$(basename "$file")" - chown 5000:5000 "/tmp/$(basename "$file")" - mv "/tmp/$(basename "$file")" "$file" + "$file" > "/tmp/$(basename "$file")" + if [[ -s "/tmp/$(basename "$file")" ]]; then + chmod 600 "/tmp/$(basename "$file")" + chown 5000:5000 "/tmp/$(basename "$file")" + mv "/tmp/$(basename "$file")" "$file" else - rm "/tmp/$(basename "$file")" + rm "/tmp/$(basename "$file")" fi fi -done - -# Encrypt /var/vmail -find /var/vmail/ -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do -if [[ $(head -c7 "$file") != "CRYPTED" ]]; then +done

      +

      Encrypt /var/vmail

      +

      find /var/vmail/ -type f -regextype egrep -regex '.S=.W=.*' | while read -r file; do +if [[ $(head -c7 "$file") != "CRYPTED" ]]; then doveadm fs put crypt private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ - "$file" "$file" - chmod 600 "$file" - chown 5000:5000 "$file" + "$file" "$file" + chmod 600 "$file" + chown 5000:5000 "$file" fi done -

      +```


      @@ -2522,7 +2529,7 @@ done - + diff --git a/en/manual-guides/Dovecot/u_e-dovecot-more/index.html b/en/manual-guides/Dovecot/u_e-dovecot-more/index.html index f7c152150..7391e962b 100644 --- a/en/manual-guides/Dovecot/u_e-dovecot-more/index.html +++ b/en/manual-guides/Dovecot/u_e-dovecot-more/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2442,25 +2442,19 @@

      doveadm quota

      The quota get and quota recalc1 commands are used to display or recalculate the current user's quota usage. The reported values are in kilobytes.

      To list the current quota status for a user / mailbox, do:

      -
      doveadm quota get -u 'mailbox@example.org'
      -
      +

      doveadm quota get -u 'mailbox@example.org'

      To list the quota storage value for all users, do:

      -
      doveadm quota get -A |grep "STORAGE"
      -
      +

      doveadm quota get -A |grep "STORAGE"

      Recalculate a single user's quota usage:

      -
      doveadm quota recalc -u 'mailbox@example.org'
      -
      +

      doveadm quota recalc -u 'mailbox@example.org'

      The doveadm search2 command is used to find messages matching your query. It can return the username, mailbox-GUID / -UID and message-GUIDs / -UIDs.

      To view the number of messages, by user, in their .Trash folder:

      -
      doveadm search -A mailbox 'Trash' | awk '{print $1}' | sort | uniq -c
      -
      +

      doveadm search -A mailbox 'Trash' | awk '{print $1}' | sort | uniq -c

      Show all messages in a user's inbox older then 90 days:

      -
      doveadm search -u 'mailbox@example.org' mailbox 'INBOX' savedbefore 90d
      -
      +

      doveadm search -u 'mailbox@example.org' mailbox 'INBOX' savedbefore 90d

      Show all messages in any folder that are older then 30 days for mailbox@example.org:

      -
      doveadm search -u 'mailbox@example.org' mailbox "*" savedbefore 30d
      -
      +

      doveadm search -u 'mailbox@example.org' mailbox "*" savedbefore 30d


        @@ -2591,7 +2585,7 @@ - + diff --git a/en/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html b/en/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html index 3b7bf4250..38229a8c2 100644 --- a/en/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html +++ b/en/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2426,28 +2426,25 @@

        Create a new public namespace "Public" and a mailbox "Develcow" inside that namespace:

        Edit or create data/conf/dovecot/extra.conf, add:

        -
        namespace {
        +

        namespace { type = public separator = / prefix = Public/ location = maildir:/var/vmail/public:INDEXPVT=~/public subscriptions = yes - mailbox "Develcow" { + mailbox "Develcow" { auto = subscribe } -} -

        +}

        :INDEXPVT=~/public can be omitted if per-user seen flags are not wanted.

        The new mailbox in the public namespace will be auto-subscribed by users.

        To allow all authenticated users access full to that new mailbox (not the whole namespace), run:

        -
        docker-compose exec dovecot-mailcow doveadm acl set -A "Public/Develcow" "authenticated" lookup read write write-seen write-deleted insert post delete expunge create
        -
        +

        docker-compose exec dovecot-mailcow doveadm acl set -A "Public/Develcow" "authenticated" lookup read write write-seen write-deleted insert post delete expunge create

        Adjust the command to your needs if you like to assign more granular rights per user (use -u user@domain instead of -A for example).

        Allow authenticated users access to the whole public namespace

        To allow all authenticated users access full access to the whole public namespace and its subfolders, create a new dovecot-acl file in the namespace root directory:

        Open/edit/create /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/public/dovecot-acl (adjust the path accordingly) to create the global ACL file with the following content:

        -
        authenticated kxeilprwts
        -
        +

        authenticated kxeilprwts

        kxeilprwts equals to lookup read write write-seen write-deleted insert post delete expunge create.

        You can use doveadm acl set -u user@domain "Public/Develcow" user=user@domain lookup read to limit access for a single user. You may also turn it around to limit access for all users to "lr" and grant only some users full access.

        See Dovecot ACL for further information about ACL.

        @@ -2570,7 +2567,7 @@ - + diff --git a/en/manual-guides/Dovecot/u_e-dovecot-static_master/index.html b/en/manual-guides/Dovecot/u_e-dovecot-static_master/index.html index 6b4f7988e..2cb759b40 100644 --- a/en/manual-guides/Dovecot/u_e-dovecot-static_master/index.html +++ b/en/manual-guides/Dovecot/u_e-dovecot-static_master/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2379,9 +2379,8 @@

        That's recommended and should not be changed.

        If you need the user to be static anyway, please specify two variables in mailcow.conf.

        Both parameters must not be empty!

        -
        DOVECOT_MASTER_USER=mymasteruser
        -DOVECOT_MASTER_PASS=mysecretpass
        -
        +

        DOVECOT_MASTER_USER=mymasteruser +DOVECOT_MASTER_PASS=mysecretpass

        Run docker-compose up -d to apply your changes.

        The static master username will be expanded to DOVECOT_MASTER_USER@mailcow.local.

        To login as test@example.org this would equal to test@example.org*mymasteruser@mailcow.local with the specified password above.

        @@ -2506,7 +2505,7 @@ No master user is required.

        - + diff --git a/en/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html b/en/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html index a6d15e904..28a2e5f9f 100644 --- a/en/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html +++ b/en/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2470,41 +2470,39 @@

        Newer Docker versions seem to complain about existing volumes. You can fix this temporarily by removing the existing volume and start mailcow with the override file. But it seems to be problematic after a reboot (needs to be confirmed).

      An easy, dirty, yet stable workaround is to stop mailcow (docker-compose down), remove /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data and create a new link to your remote filesystem location, for example:

      -
      mv /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data_backup
      -ln -s /mnt/volume-xy/vmail_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data
      -
      +

      mv /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data_backup +ln -s /mnt/volume-xy/vmail_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data

      Start mailcow afterwards.


      The "old" way

      If you want to use another folder for the vmail-volume, you can create a docker-compose.override.yml file and add the following content:

      -
      version: '2.1'
      +

      version: '2.1' volumes: vmail-vol-1: driver_opts: type: none device: /data/mailcow/vmail - o: bind -

      + o: bind

      Moving an existing vmail folder:

      • Locate the current vmail folder by its "Mountpoint" attribute: docker volume inspect mailcowdockerized_vmail-vol-1
      -
      [
      +

      hl_lines="10" +[ { - "CreatedAt": "2019-06-16T22:08:34+02:00", - "Driver": "local", - "Labels": { - "com.docker.compose.project": "mailcowdockerized", - "com.docker.compose.version": "1.23.2", - "com.docker.compose.volume": "vmail-vol-1" + "CreatedAt": "2019-06-16T22:08:34+02:00", + "Driver": "local", + "Labels": { + "com.docker.compose.project": "mailcowdockerized", + "com.docker.compose.version": "1.23.2", + "com.docker.compose.volume": "vmail-vol-1" }, - "Mountpoint": "/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data", - "Name": "mailcowdockerized_vmail-vol-1", - "Options": null, - "Scope": "local" + "Mountpoint": "/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data", + "Name": "mailcowdockerized_vmail-vol-1", + "Options": null, + "Scope": "local" } -] -

      +]

      • Copy the content of the Mountpoint folder to the new location (e.g. /data/mailcow/vmail) using cp -a, rsync -a or a similar non strcuture breaking copy command
      • Stop mailcow by executing docker-compose down from within your mailcow root folder (e.g. /opt/mailcow-dockerized)
      • @@ -2631,7 +2629,7 @@ volumes: - + diff --git a/en/manual-guides/Nginx/u_e-nginx_custom/index.html b/en/manual-guides/Nginx/u_e-nginx_custom/index.html index e255e4cb3..1c552b7b8 100644 --- a/en/manual-guides/Nginx/u_e-nginx_custom/index.html +++ b/en/manual-guides/Nginx/u_e-nginx_custom/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2472,9 +2472,9 @@

        New site

        To create persistent (over updates) sites hosted by mailcow: dockerized, a new site configuration must be placed inside data/conf/nginx/:

        A good template to begin with:

        -
        nano data/conf/nginx/my_custom_site.conf
        -
        -
        server {
        +

        nano data/conf/nginx/my_custom_site.conf

        +

        ``` hl_lines="16" +server { ssl_certificate /etc/ssl/mail/cert.pem; ssl_certificate_key /etc/ssl/mail/key.pem; ssl_protocols TLSv1.2 TLSv1.3; @@ -2489,29 +2489,27 @@ # Location: data/web root /web; # Location: data/web/mysite.com - #root /web/mysite.com - include /etc/nginx/conf.d/listen_plain.active; + #root /web/mysite.com + include /etc/nginx/conf.d/listen_plain.active; include /etc/nginx/conf.d/listen_ssl.active; server_name mysite.example.org; - server_tokens off; - - # This allows acme to be validated even with a different web root + server_tokens off;

        +

        # This allows acme to be validated even with a different web root location ^~ /.well-known/acme-challenge/ { - default_type "text/plain"; + default_type "text/plain"; rewrite /.well-known/acme-challenge/(.*) /$1 break; root /web/.well-known/acme-challenge/; - } - - if ($scheme = http) { + }

        +

        if ($scheme = http) { return 301 https://$server_name$request_uri; } } -

        +```

        New site with proxy to a remote location

        Another example with a reverse proxy configuration:

        -
        nano data/conf/nginx/my_custom_site.conf
        -
        -
        server {
        +

        nano data/conf/nginx/my_custom_site.conf

        +

        ``` hl_lines="16 28" +server { ssl_certificate /etc/ssl/mail/cert.pem; ssl_certificate_key /etc/ssl/mail/key.pem; ssl_protocols TLSv1.2 TLSv1.3; @@ -2526,20 +2524,17 @@ root /web; include /etc/nginx/conf.d/listen_plain.active; include /etc/nginx/conf.d/listen_ssl.active; - server_name example.domain.tld; - server_tokens off; - - location ^~ /.well-known/acme-challenge/ { + server_name example.domain.tld; + server_tokens off;

        +

        location ^~ /.well-known/acme-challenge/ { allow all; - default_type "text/plain"; - } - - if ($scheme = http) { + default_type "text/plain"; + }

        +

        if ($scheme = http) { return 301 https://$host$request_uri; - } - - location / { - proxy_pass http://service:3000/; + }

        +

        location / { + proxy_pass http://service:3000/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -2547,18 +2542,16 @@ client_max_body_size 0; } } -

        +```

        Config expansion in mailcows Nginx

        The filename used for a new site is not important, as long as the filename carries a .conf extension.

        It is also possible to extend the configuration of the default file site.conf file:

        -
        nano data/conf/nginx/site.my_content.custom
        -
        +

        nano data/conf/nginx/site.my_content.custom

        This filename does not need to have a ".conf" extension but follows the pattern site.*.custom, where * is a custom name.

        If PHP is to be included in a custom site, please use the PHP-FPM listener on phpfpm:9002 or create a new listener in data/conf/phpfpm/php-fpm.d/pools.conf.

        Restart Nginx (and PHP-FPM, if a new listener was created):

        -
        docker-compose restart nginx-mailcow
        -docker-compose restart php-fpm-mailcow
        -
        +

        docker-compose restart nginx-mailcow +docker-compose restart php-fpm-mailcow


        @@ -2678,7 +2671,7 @@ docker-compose restart php-fpm-mailcow - + diff --git a/en/manual-guides/Nginx/u_e-nginx_webmail-site/index.html b/en/manual-guides/Nginx/u_e-nginx_webmail-site/index.html index 63293154a..8964a6b30 100644 --- a/en/manual-guides/Nginx/u_e-nginx_webmail-site/index.html +++ b/en/manual-guides/Nginx/u_e-nginx_webmail-site/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2378,7 +2378,8 @@

        IMPORTANT: This guide only applies to non SNI enabled configurations. The certificate path needs to be adjusted if SNI is enabled. Something like ssl_certificate,key /etc/ssl/mail/webmail.example.org/cert.pem,key.pem; will do. But: The certificate should be acquired first and only after the certificate exists a site config should be created. Nginx will fail to start if it cannot find the certificate and key.

        To create a subdomain webmail.example.org and redirect it to SOGo, you need to create a new Nginx site. Take care of "CHANGE_TO_MAILCOW_HOSTNAME"!

        nano data/conf/nginx/webmail.conf

        -
        server {
        +

        ``` hl_lines="9 17" +server { ssl_certificate /etc/ssl/mail/cert.pem; ssl_certificate_key /etc/ssl/mail/key.pem; index index.php index.html; @@ -2386,23 +2387,21 @@ root /web; include /etc/nginx/conf.d/listen_plain.active; include /etc/nginx/conf.d/listen_ssl.active; - server_name webmail.example.org; - server_tokens off; + server_name webmail.example.org; + server_tokens off; location ^~ /.well-known/acme-challenge/ { allow all; - default_type "text/plain"; + default_type "text/plain"; + }

        +

        location / { + return 301 https://CHANGE_TO_MAILCOW_HOSTNAME/SOGo; } - - location / { - return 301 https://CHANGE_TO_MAILCOW_HOSTNAME/SOGo; - } } -

        +```

        Save and restart Nginx: docker-compose restart nginx-mailcow.

        Now open mailcow.conf and find ADDITIONAL_SAN. Add webmail.example.org to this array, don't use quotes!

        -
        ADDITIONAL_SAN=webmail.example.org
        -
        +

        ADDITIONAL_SAN=webmail.example.org

        Run docker-compose up -d. See "acme-mailcow" and "nginx-mailcow" logs if anything fails.


        @@ -2523,7 +2522,7 @@ Add webmail.example.org to this array, don't use quotes!

        - + diff --git a/en/manual-guides/Postfix/u_e-postfix-attachment_size/index.html b/en/manual-guides/Postfix/u_e-postfix-attachment_size/index.html index 8df45b548..221720979 100644 --- a/en/manual-guides/Postfix/u_e-postfix-attachment_size/index.html +++ b/en/manual-guides/Postfix/u_e-postfix-attachment_size/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,8 +2377,7 @@

        Open data/conf/postfix/extra.cf and set the message_size_limit accordingly in bytes. See main.cf for the default value.

        Restart Postfix:

        -
        docker-compose restart postfix-mailcow
        -
        +

        docker-compose restart postfix-mailcow


        @@ -2498,7 +2497,7 @@ - + diff --git a/en/manual-guides/Postfix/u_e-postfix-custom_transport/index.html b/en/manual-guides/Postfix/u_e-postfix-custom_transport/index.html index c76144b2e..f79a04bed 100644 --- a/en/manual-guides/Postfix/u_e-postfix-custom_transport/index.html +++ b/en/manual-guides/Postfix/u_e-postfix-custom_transport/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2497,7 +2497,7 @@ - + diff --git a/en/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html b/en/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html index fea0045f0..67b8c4748 100644 --- a/en/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html +++ b/en/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2444,14 +2444,11 @@

        Deprecated guide (DO NOT USE ON NEWER MAILCOWS!)

        This option is not best-practice and should only be implemented when there is no other option available to achieve whatever you are trying to do.

        Simply create a file data/conf/postfix/check_sasl_access and enter the following content. This user must exist in your installation and needs to authenticate before sending mail. -

        user-to-allow-everything@example.com OK
        -

        +user-to-allow-everything@example.com OK

        Open data/conf/postfix/main.cf and find smtpd_sender_restrictions. Prepend check_sasl_access hash:/opt/postfix/conf/check_sasl_access like this: -

        smtpd_sender_restrictions = check_sasl_access hash:/opt/postfix/conf/check_sasl_access reject_authenticated_sender_login_mismatch [...]
        -

        +smtpd_sender_restrictions = check_sasl_access hash:/opt/postfix/conf/check_sasl_access reject_authenticated_sender_login_mismatch [...]

        Run postmap on check_sasl_access:

        -
        docker-compose exec postfix-mailcow postmap /opt/postfix/conf/check_sasl_access
        -
        +

        docker-compose exec postfix-mailcow postmap /opt/postfix/conf/check_sasl_access

        Restart the Postfix container.


        @@ -2572,7 +2569,7 @@ - + diff --git a/en/manual-guides/Postfix/u_e-postfix-extra_cf/index.html b/en/manual-guides/Postfix/u_e-postfix-extra_cf/index.html index ca5026179..8231f17a4 100644 --- a/en/manual-guides/Postfix/u_e-postfix-extra_cf/index.html +++ b/en/manual-guides/Postfix/u_e-postfix-extra_cf/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2379,8 +2379,7 @@

        Postfix will complain about duplicate values once after starting postfix-mailcow, this is intended.

        Syslog-ng was configured to hide those warnings while Postfix is running, to not spam the log files with unnecessary information every time a service is used.

        Restart postfix-mailcow to apply your changes:

        -
        docker-compose restart postfix-mailcow
        -
        +

        docker-compose restart postfix-mailcow


        @@ -2500,7 +2499,7 @@ - + diff --git a/en/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html b/en/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html index a080fb00e..8ed314399 100644 --- a/en/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html +++ b/en/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,13 +2376,11 @@

        Statistics with pflogsumm

        To use pflogsumm with the default logging driver, we need to query postfix-mailcow via docker logs and direct the output to pflogsumm:

        -
        docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | pflogsumm
        -
        +

        docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | pflogsumm

        The above log output is limited to the last 24 hours.

        It is also possible to create a daily pflogsumm report via cron. Create the /etc/cron.d/pflogsumm file with the following content:

        -
        SHELL=/bin/bash
        -59 23 * * root docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | /usr/sbin/pflogsumm -d today | mail -s "Postfix Report of $(date)" postmaster@example.net
        -
        +

        SHELL=/bin/bash +59 23 * * root docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | /usr/sbin/pflogsumm -d today | mail -s "Postfix Report of $(date)" postmaster@example.net

        To work, a local postfix must be installed on the server, which relays to the mailcow postfix.

        More detailed information can be found in section Post installation tasks -> Local MTA on Dockerhost.

        Based on the postfix logs of the last 24 hours, this example then sends a pflogsumm report to postmaster@example.net every day at 23:59:00.

        @@ -2506,7 +2504,7 @@ - + diff --git a/en/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html b/en/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html index 88630bd55..c9067183a 100644 --- a/en/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html +++ b/en/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2373,19 +2382,18 @@ -

        Whitelist IP in Postscreen

        -

        IPs can be removed from Postscreen and therefore also from RBL checks in data/conf/postfix/custom_postscreen_whitelist.cidr.

        Postscreen does multiple checks to identify malicious senders. In most cases you want to whitelist an IP to exclude it from blacklist lookups.

        The format of the file is as follows:

        CIDR ACTION

        Where CIDR is a single IP address or IP range in CIDR notation, and action is either "permit" or "reject".

        Example:

        -
        +```

        The file is reloaded on the fly, postfix restart is not required.


        @@ -2506,7 +2514,7 @@ - + diff --git a/en/manual-guides/Postfix/u_e-postfix-relayhost/index.html b/en/manual-guides/Postfix/u_e-postfix-relayhost/index.html index 10a135454..e34e97916 100644 --- a/en/manual-guides/Postfix/u_e-postfix-relayhost/index.html +++ b/en/manual-guides/Postfix/u_e-postfix-relayhost/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2605,7 +2605,7 @@ Keep in mind the credentials will be stored in plain text.

        - + diff --git a/en/manual-guides/Postfix/u_e-postfix-trust_networks/index.html b/en/manual-guides/Postfix/u_e-postfix-trust_networks/index.html index d591721b2..7bcc685fd 100644 --- a/en/manual-guides/Postfix/u_e-postfix-trust_networks/index.html +++ b/en/manual-guides/Postfix/u_e-postfix-trust_networks/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2475,15 +2475,13 @@

        IPv4 hosts/subnets

        To add the subnet 192.168.2.0/24 to the trusted networks you may use the following configuration, depending on your IPV4_NETWORK and IPV6_NETWORK scopes:

        Edit data/conf/postfix/extra.cf:

        -
        mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 192.168.2.0/24
        -
        +

        mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 192.168.2.0/24

        Run docker-compose restart postfix-mailcow to apply your new settings.

        IPv6 hosts/subnets

        Adding IPv6 hosts is done the same as IPv4, however the subnet needs to be placed in brackets [] with the netmask appended.

        To add the subnet 2001:db8::/32 to the trusted networks you may use the following configuration, depending on your IPV4_NETWORK and IPV6_NETWORK scopes:

        Edit data/conf/postfix/extra.cf:

        -
        mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 [2001:db8::]/32
        -
        +

        mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 [2001:db8::]/32

        Run docker-compose restart postfix-mailcow to apply your new settings.

        Info

        @@ -2608,7 +2606,7 @@ - + diff --git a/en/manual-guides/Redis/u_e-redis/index.html b/en/manual-guides/Redis/u_e-redis/index.html index e536d801c..6a01a4df6 100644 --- a/en/manual-guides/Redis/u_e-redis/index.html +++ b/en/manual-guides/Redis/u_e-redis/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1832,6 +1832,24 @@ +
      + + + + + + + + + +
    • + + docker-compose exec redis-mailcow redis-cli + + + -
    • - - - - @@ -2458,6 +2471,24 @@ + + + + + + + + + + +
    • + + docker-compose exec redis-mailcow redis-cli + + + -
    • - - - - @@ -2500,33 +2526,29 @@ -

      Redis

      -

      Redis is used as a key-value store for rspamd's and (some of) mailcow's settings and data. If you are unfamiliar with redis please read the introduction to redis and maybe visit this wonderful guide on how to use it.

      Client

      To connect to the redis cli execute:

      -
      docker-compose exec redis-mailcow redis-cli
      -
      +

      docker-compose exec redis-mailcow redis-cli

      Debugging

      Here are some useful commands for the redis-cli for debugging:

      MONITOR

      Listens for all requests received by the server in real time:

      -
      # docker-compose exec redis-mailcow redis-cli
      -127.0.0.1:6379> monitor
      +

      ```

      +

      docker-compose exec redis-mailcow redis-cli

      +

      127.0.0.1:6379> monitor OK -1494077286.401963 [0 172.22.1.253:41228] "SMEMBERS" "BAYES_SPAM_keys" -1494077288.292970 [0 172.22.1.253:41229] "SMEMBERS" "BAYES_SPAM_keys" +1494077286.401963 [0 172.22.1.253:41228] "SMEMBERS" "BAYES_SPAM_keys" +1494077288.292970 [0 172.22.1.253:41229] "SMEMBERS" "BAYES_SPAM_keys" [...] -

      +```

      KEYS

      Get all keys matching your pattern:

      -
      KEYS *
      -
      +

      KEYS *

      PING

      Test a connection:

      -
      127.0.0.1:6379> PING
      -PONG
      -
      +

      127.0.0.1:6379> PING +PONG

      If you want to know more, here is a cheat sheet.


      @@ -2647,7 +2669,7 @@ PONG - + diff --git a/en/manual-guides/Rspamd/u_e-rspamd/index.html b/en/manual-guides/Rspamd/u_e-rspamd/index.html index 2c9cb708f..eb67fcd24 100644 --- a/en/manual-guides/Rspamd/u_e-rspamd/index.html +++ b/en/manual-guides/Rspamd/u_e-rspamd/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1838,6 +1838,26 @@ + + + + + +
    • + + Ham + + +
    • + +
    • + + Spam + + +
    • + + + + + +
    • + + Ham + + +
    • + +
    • + + Spam + + +
    • open text editor and paste data from clipboard (Ctrl+V), you should get minified CSS, save it
    • copy CSS file to mailcow server data/conf/sogo/custom-theme.css
    • edit data/conf/sogo/sogo.conf and set SOGoUIxDebugEnabled = NO;
    • append/create docker-compose.override.yml with: -
      version: '2.1'
      -
      -services:
      +```
      +version: '2.1'
    • + +

      services: sogo-mailcow: volumes: - ./data/conf/sogo/custom-theme.css:/usr/lib/GNUstep/SOGo/WebServerResources/css/theme-default.css:z -

      -
    • run docker-compose up -d
    • -
    • run docker-compose restart memcached-mailcow
    • - +`` +11. rundocker-compose up -d12. rundocker-compose restart memcached-mailcow`

      Reset to SOGo default theme

      1. checkout data/conf/sogo/custom-theme.js by executing git fetch ; git checkout origin/master data/conf/sogo/custom-theme.js data/conf/sogo/custom-theme.js
      2. find in data/conf/sogo/custom-theme.js: -
        // Apply new palettes to the default theme, remap some of the hues
        -    $mdThemingProvider.theme('default')
        -      .primaryPalette('green-cow', {
        -        'default': '400',  // background color of top toolbars
        -        'hue-1': '400',
        -        'hue-2': '600',    // background color of sidebar toolbar
        -        'hue-3': 'A700'
        +// Apply new palettes to the default theme, remap some of the hues
        +    $mdThemingProvider.theme('default')
        +      .primaryPalette('green-cow', {
        +        'default': '400',  // background color of top toolbars
        +        'hue-1': '400',
        +        'hue-2': '600',    // background color of sidebar toolbar
        +        'hue-3': 'A700'
               })
        -      .accentPalette('green', {
        -        'default': '600',  // background color of fab buttons and login screen
        -        'hue-1': '300',    // background color of center list toolbar
        -        'hue-2': '300',    // highlight color for selected mail and current day calendar
        -        'hue-3': 'A700'
        +      .accentPalette('green', {
        +        'default': '600',  // background color of fab buttons and login screen
        +        'hue-1': '300',    // background color of center list toolbar
        +        'hue-2': '300',    // highlight color for selected mail and current day calendar
        +        'hue-3': 'A700'
               })
        -      .backgroundPalette('frost-grey');
        -
        + .backgroundPalette('frost-grey'); and replace it with: -
            $mdThemingProvider.theme('default');
        -
      3. +$mdThemingProvider.theme('default');
      4. remove from docker-compose.override.yml volume mount in sogo-mailcow: -
        - ./data/conf/sogo/custom-theme.css:/usr/lib/GNUstep/SOGo/WebServerResources/css/theme-default.css:z
        -
      5. +``` +
      6. ./data/conf/sogo/custom-theme.css:/usr/lib/GNUstep/SOGo/WebServerResources/css/theme-default.css:z +```
      7. run docker-compose up -d
      8. run docker-compose restart memcached-mailcow
      @@ -2581,16 +2578,14 @@ After you replaced said file you need to restart SOGo and Memcached containers b

      Domains are usually isolated from eachother.

      You can change that by modifying data/conf/sogo/sogo.conf:

      Search... -

         // SOGoDomainsVisibility = (
      +// SOGoDomainsVisibility = (
           //  (domain1.tld, domain5.tld),
           //  (domain3.tld, domain2.tld)
      -    // );
      -
      + // ); ...and replace it by - for example:

      -
          SOGoDomainsVisibility = (
      +

      SOGoDomainsVisibility = ( (example.org, example.com, example.net) - ); -

      + );

      Restart SOGo: docker-compose restart sogo-mailcow

      Disable password changing

      Edit data/conf/sogo/sogo.conf and change SOGoPasswordChangeEnabled to NO. Please do not add a new parameter.

      @@ -2716,7 +2711,7 @@ After you replaced said file you need to restart SOGo and Memcached containers b - + diff --git a/en/manual-guides/Unbound/u_e-unbound-fwd/index.html b/en/manual-guides/Unbound/u_e-unbound-fwd/index.html index edcff9554..82ad6a866 100644 --- a/en/manual-guides/Unbound/u_e-unbound-fwd/index.html +++ b/en/manual-guides/Unbound/u_e-unbound-fwd/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2444,18 +2444,15 @@ Important: Only DNSSEC validating DNS services will work.

      Method A, Unbound

      Edit data/conf/unbound/unbound.conf and append the following parameters:

      -
      forward-zone:
      -  name: "."
      +

      forward-zone: + name: "." forward-addr: 8.8.8.8 # DO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE - forward-addr: 8.8.4.4 # DO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE -

      + forward-addr: 8.8.4.4 # DO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE

      Restart Unbound:

      -
      docker-compose restart unbound-mailcow
      -
      +

      docker-compose restart unbound-mailcow

      Method B, Override file

      -
      cd /opt/mailcow-dockerized
      -cp helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml .
      -
      +

      cd /opt/mailcow-dockerized +cp helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml .

      Edit docker-compose.override.yml and adjust the IP.

      Run docker-compose down ; docker-compose up -d.

      @@ -2577,7 +2574,7 @@ cp helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.over - + diff --git a/en/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html b/en/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html index a95e1b1c2..142c84875 100644 --- a/en/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html +++ b/en/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2677,7 +2677,7 @@

      Watchdog uses default values for all thresholds defined in docker-compose.yml.

      The default values will work for most setups. Example: -

      - NGINX_THRESHOLD=${NGINX_THRESHOLD:-5}
      +- NGINX_THRESHOLD=${NGINX_THRESHOLD:-5}
       - UNBOUND_THRESHOLD=${UNBOUND_THRESHOLD:-5}
       - REDIS_THRESHOLD=${REDIS_THRESHOLD:-5}
       - MYSQL_THRESHOLD=${MYSQL_THRESHOLD:-5}
      @@ -2694,8 +2694,7 @@ Example:
       - RSPAMD_THRESHOLD=${RSPAMD_THRESHOLD:-5}
       - OLEFY_THRESHOLD=${OLEFY_THRESHOLD:-5}
       - MAILQ_THRESHOLD=${MAILQ_THRESHOLD:-20}
      -- MAILQ_CRIT=${MAILQ_CRIT:-30}
      -

      +- MAILQ_CRIT=${MAILQ_CRIT:-30}

      To adjust them just add necessary threshold variables (e.g. MAILQ_THRESHOLD=10) to mailcow.conf and run docker-compose up -d.

      Thresholds descriptions

      NGINX_THRESHOLD

      @@ -2851,7 +2850,7 @@ Example: - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html index bddbeef14..1405391e4 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2502,7 +2502,7 @@ - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html index b82e14b88..a20e280a4 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2518,7 +2518,7 @@ - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html index 6673af03d..10eb03aea 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2496,7 +2496,7 @@ - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html index 01a2a24c9..a8058f928 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2581,7 +2581,7 @@ - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html index efb38b74d..5e5134f8e 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2578,7 +2578,7 @@ If this is the case, it is recommended to reset the Netfilter regex rules by cli - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html index 6f2d1ecd6..032751324 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2506,7 +2506,7 @@ - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html index 735136136..eb0687759 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2497,7 +2497,7 @@ - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html index 929eee3cc..9e67ec357 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2501,7 +2501,7 @@ For a domain wide black- and whitelist please check our guide on {"base": "../../../..", "features": ["navigation.top", "navigation.tracking"], "search": "../../../../assets/javascripts/workers/search.2a1c317c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version.title": "Select version"}} - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html index d2f24e4f9..4e8380001 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2431,20 +2431,19 @@

      1. Move this message to a sub folder "facebook" (will be created lower case if not existing)

      2. Prepend the tag to the subject: "[facebook] Subject"

      Please note: Uppercase tags are converted to lowercase except for the first letter. If you want to keep the tag as it is, please apply the following diff and restart mailcow: -

      diff --git a/data/conf/dovecot/global_sieve_after b/data/conf/dovecot/global_sieve_after
      +diff --git a/data/conf/dovecot/global_sieve_after b/data/conf/dovecot/global_sieve_after
       index e047136e..933c4137 100644
       --- a/data/conf/dovecot/global_sieve_after
       +++ b/data/conf/dovecot/global_sieve_after
       @@ -15,7 +15,7 @@ if allof (
      -   envelope :detail :matches "to" "*",
      -   header :contains "X-Moo-Tag" "YES"
      +   envelope :detail :matches "to" "*",
      +   header :contains "X-Moo-Tag" "YES"
          ) {
      --  set :lower :upperfirst "tag" "${1}";
      -+  set "tag" "${1}";
      -   if mailboxexists "INBOX/${1}" {
      -     fileinto "INBOX/${1}";
      -   } else {
      -

      +- set :lower :upperfirst "tag" "${1}"; ++ set "tag" "${1}"; + if mailboxexists "INBOX/${1}" { + fileinto "INBOX/${1}"; + } else {


      @@ -2564,7 +2563,7 @@ index e047136e..933c4137 100644 - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html index 9c9c579ae..256e56b04 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2604,7 +2604,7 @@ To view them simply click on the small plus symbol on the left of your Domain/Ma - + diff --git a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html index 83bfdfe4c..00ae28760 100644 --- a/en/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html +++ b/en/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2779,7 +2779,7 @@ These vendor certificates are only used to verify original hardware, not to secu - + diff --git a/en/manual-guides/u_e-80_to_443/index.html b/en/manual-guides/u_e-80_to_443/index.html index 087fbbc00..9e73f4ab0 100644 --- a/en/manual-guides/u_e-80_to_443/index.html +++ b/en/manual-guides/u_e-80_to_443/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,27 +2377,24 @@

      Do not use the config below for reverse proxy setups, please see our reverse proxy guide for this, which includes a redirect from HTTP to HTTPS.

      Open mailcow.conf and set HTTP_BIND= - if not already set.

      Create a new file data/conf/nginx/redirect.conf and add the following server config to the file:

      -
      server {
      +

      server { root /web; listen 80 default_server; listen [::]:80 default_server; include /etc/nginx/conf.d/server_name.active; - if ( $request_uri ~* "%0A|%0D" ) { return 403; } + if ( $request_uri ~* "%0A|%0D" ) { return 403; } location ^~ /.well-known/acme-challenge/ { allow all; - default_type "text/plain"; + default_type "text/plain"; } location / { return 301 https://$host$uri$is_args$args; } -} -

      +}

      In case you changed the HTTP_BIND parameter, recreate the container:

      -
      docker-compose up -d
      -
      +

      docker-compose up -d

      Otherwise restart Nginx:

      -
      docker-compose restart nginx-mailcow
      -
      +

      docker-compose restart nginx-mailcow


      @@ -2517,7 +2514,7 @@ - + diff --git a/en/manual-guides/u_e-autodiscover_config/index.html b/en/manual-guides/u_e-autodiscover_config/index.html index 5cb587396..887aca6f8 100644 --- a/en/manual-guides/u_e-autodiscover_config/index.html +++ b/en/manual-guides/u_e-autodiscover_config/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2378,45 +2378,44 @@ Keep in mind, that ActiveSync should NOT be used with a desktop client.

      Open/create data/web/inc/vars.local.inc.php and add your changes to the configuration array.

      Changes will be merged with "$autodiscover_config" in data/web/inc/vars.inc.php):

      -
      <?php
      +

      <?php $autodiscover_config = array( - // General autodiscover service type: "activesync" or "imap" + // General autodiscover service type: "activesync" or "imap" // emClient uses autodiscover, but does not support ActiveSync. mailcow excludes emClient from ActiveSync. - 'autodiscoverType' => 'activesync', + 'autodiscoverType' => 'activesync', // If autodiscoverType => activesync, also use ActiveSync (EAS) for Outlook desktop clients (>= Outlook 2013 on Windows) // Outlook for Mac does not support ActiveSync - 'useEASforOutlook' => 'yes', - // Please don't use STARTTLS-enabled service ports in the "port" variable. + 'useEASforOutlook' => 'yes', + // Please don't use STARTTLS-enabled service ports in the "port" variable. // The autodiscover service will always point to SMTPS and IMAPS (TLS-wrapped services). - // The autoconfig service will additionally announce the STARTTLS-enabled ports, specified in the "tlsport" variable. - 'imap' => array( - 'server' => $mailcow_hostname, - 'port' => array_pop(explode(':', getenv('IMAPS_PORT'))), - 'tlsport' => array_pop(explode(':', getenv('IMAP_PORT'))), + // The autoconfig service will additionally announce the STARTTLS-enabled ports, specified in the "tlsport" variable. + 'imap' => array( + 'server' => $mailcow_hostname, + 'port' => array_pop(explode(':', getenv('IMAPS_PORT'))), + 'tlsport' => array_pop(explode(':', getenv('IMAP_PORT'))), ), - 'pop3' => array( - 'server' => $mailcow_hostname, - 'port' => array_pop(explode(':', getenv('POPS_PORT'))), - 'tlsport' => array_pop(explode(':', getenv('POP_PORT'))), + 'pop3' => array( + 'server' => $mailcow_hostname, + 'port' => array_pop(explode(':', getenv('POPS_PORT'))), + 'tlsport' => array_pop(explode(':', getenv('POP_PORT'))), ), - 'smtp' => array( - 'server' => $mailcow_hostname, - 'port' => array_pop(explode(':', getenv('SMTPS_PORT'))), - 'tlsport' => array_pop(explode(':', getenv('SUBMISSION_PORT'))), + 'smtp' => array( + 'server' => $mailcow_hostname, + 'port' => array_pop(explode(':', getenv('SMTPS_PORT'))), + 'tlsport' => array_pop(explode(':', getenv('SUBMISSION_PORT'))), ), - 'activesync' => array( - 'url' => 'https://'.$mailcow_hostname.($https_port == 443 ? '' : ':'.$https_port).'/Microsoft-Server-ActiveSync', + 'activesync' => array( + 'url' => 'https://'.$mailcow_hostname.($https_port == 443 ? '' : ':'.$https_port).'/Microsoft-Server-ActiveSync', ), - 'caldav' => array( - 'server' => $mailcow_hostname, - 'port' => $https_port, + 'caldav' => array( + 'server' => $mailcow_hostname, + 'port' => $https_port, ), - 'carddav' => array( - 'server' => $mailcow_hostname, - 'port' => $https_port, + 'carddav' => array( + 'server' => $mailcow_hostname, + 'port' => $https_port, ), -); -

      +);

      To always use IMAP and SMTP instead of EAS, set 'autodiscoverType' => 'imap'.

      Disable ActiveSync for Outlook desktop clients by setting "useEASforOutlook" to "no".

      @@ -2538,7 +2537,7 @@ $autodiscover_config = array( - + diff --git a/en/manual-guides/u_e-reeanble-weak-protocols/index.html b/en/manual-guides/u_e-reeanble-weak-protocols/index.html index 643fd25a0..2016dfc20 100644 --- a/en/manual-guides/u_e-reeanble-weak-protocols/index.html +++ b/en/manual-guides/u_e-reeanble-weak-protocols/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,15 +2377,12 @@

      Unauthenticated mail via SMTP on port 25/tcp does still accept >= TLS 1.0 . It is better to accept a weak encryption than none at all.

      How to re-enable weak protocols?

      Edit data/conf/postfix/extra.cf:

      -
      submission_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
      -smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
      -
      +

      submission_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 +smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3

      Edit data/conf/dovecot/extra.conf:

      -
      ssl_min_protocol = TLSv1
      -
      +

      ssl_min_protocol = TLSv1

      Restart the affected services:

      -
      docker-compose restart postfix-mailcow dovecot-mailcow
      -
      +

      docker-compose restart postfix-mailcow dovecot-mailcow

      Hint: You can enable TLS 1.2 in Windows 7.


      @@ -2506,7 +2503,7 @@ smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 - + diff --git a/en/manual-guides/u_e-update-hooks/index.html b/en/manual-guides/u_e-update-hooks/index.html index 9c3787ea6..2fe39a2c0 100644 --- a/en/manual-guides/u_e-update-hooks/index.html +++ b/en/manual-guides/u_e-update-hooks/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2500,7 +2500,7 @@ - + diff --git a/en/manual-guides/u_e-why_unbound/index.html b/en/manual-guides/u_e-why_unbound/index.html index 2b6a207ce..24f34176b 100644 --- a/en/manual-guides/u_e-why_unbound/index.html +++ b/en/manual-guides/u_e-why_unbound/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2497,7 +2497,7 @@ Using a public resolver like Googles 4x8, OpenDNS or any other shared DNS resolv - + diff --git a/en/models/model-acl/index.html b/en/models/model-acl/index.html index bd4202486..45301deb9 100644 --- a/en/models/model-acl/index.html +++ b/en/models/model-acl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2511,7 +2511,7 @@ - + diff --git a/en/models/model-passwd/index.html b/en/models/model-passwd/index.html index ea3e2a998..52abec82a 100644 --- a/en/models/model-passwd/index.html +++ b/en/models/model-passwd/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2599,7 +2599,7 @@ With SOGo disabled, all hashing methods below will be able to be read by mailcow - + diff --git a/en/models/model-sender_rcv/index.html b/en/models/model-sender_rcv/index.html index a9d62510f..1460356f7 100644 --- a/en/models/model-sender_rcv/index.html +++ b/en/models/model-sender_rcv/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2573,7 +2573,7 @@ needs to grant you access as described above.

      - + diff --git a/en/post_installation/firststeps-disable_ipv6/index.html b/en/post_installation/firststeps-disable_ipv6/index.html index 233c1b27f..cc77ec498 100644 --- a/en/post_installation/firststeps-disable_ipv6/index.html +++ b/en/post_installation/firststeps-disable_ipv6/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,8 +2380,6 @@ -

      Disable IPv6

      -

      This is ONLY recommended if you do not have an IPv6 enabled network on your host!

      If you really need to, you can disable the usage of IPv6 in the compose file. Additionally, you can also disable the startup of container "ipv6nat-mailcow", as it's not needed if you won't use IPv6.

      @@ -2381,49 +2388,45 @@ and implement your changes to the service there. Unfortunately, this right now o

      To disable IPv6 on the mailcow network, open docker-compose.yml with your favourite text editor and search for the network section (it's near the bottom of the file).

      1. Modify docker-compose.yml

      Change enable_ipv6: true to enable_ipv6: false:

      -
      networks:
      +

      networks: mailcow-network: [...] enable_ipv6: true # <<< set to false - [...] -

      + [...]

      2. Disable ipv6nat-mailcow

      To disable the ipv6nat-mailcow container as well, go to your mailcow directory and create a new file called "docker-compose.override.yml":

      NOTE: If you already have an override file, of course don't recreate it, but merge the lines below into your existing one accordingly!

      -
      # cd /opt/mailcow-dockerized
      -# touch docker-compose.override.yml
      -
      +

      ```

      +

      cd /opt/mailcow-dockerized

      +

      touch docker-compose.override.yml

      +

      ```

      Open the file in your favourite text editor and fill in the following:

      -
      version: '2.1'
      -services:
      -
      -    ipv6nat-mailcow:
      -      image: bash:latest
      -      restart: "no"
      -      entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]
      -
      +

      ``` +version: '2.1' +services:

      +
      ipv6nat-mailcow:
      +  image: bash:latest
      +  restart: "no"
      +  entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]
      +
      +

      ```

      For these changes to be effective, you need to fully stop and then restart the stack, so containers and networks are recreated:

      -
      docker-compose down
      -docker-compose up -d
      -
      +

      docker-compose down +docker-compose up -d

      3. Disable IPv6 in unbound-mailcow

      Edit data/conf/unbound/unbound.conf and set do-ip6 to "no":

      -
      server:
      +

      server: [...] do-ip6: no - [...] -

      + [...]

      Restart Unbound:

      -
      docker-compose restart unbound-mailcow
      -
      +

      docker-compose restart unbound-mailcow

      4. Disable IPv6 in postfix-mailcow

      Create data/conf/postfix/extra.cf and set smtp_address_preference to ipv4:

      -
      smtp_address_preference = ipv4
      -inet_protocols = ipv4
      -
      +

      smtp_address_preference = ipv4 +inet_protocols = ipv4

      Restart Postfix:

      -
      docker-compose restart postfix-mailcow
      -
      +

      docker-compose restart postfix-mailcow


      @@ -2543,7 +2546,7 @@ inet_protocols = ipv4 - + diff --git a/en/post_installation/firststeps-dmarc_reporting/index.html b/en/post_installation/firststeps-dmarc_reporting/index.html index db8b7e6bc..40eef1ad4 100644 --- a/en/post_installation/firststeps-dmarc_reporting/index.html +++ b/en/post_installation/firststeps-dmarc_reporting/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2501,44 +2501,42 @@

      Enable DMARC reporting

      Create the file data/conf/rspamd/local.d/dmarc.conf and set the following content:

      -
      reporting {
      +

      reporting { enabled = true; - email = 'noreply-dmarc@example.com'; - domain = 'example.com'; - org_name = 'Example'; - helo = 'rspamd'; - smtp = 'postfix'; + email = 'noreply-dmarc@example.com'; + domain = 'example.com'; + org_name = 'Example'; + helo = 'rspamd'; + smtp = 'postfix'; smtp_port = 25; - from_name = 'Example DMARC Report'; - msgid_from = 'rspamd.mail.example.com'; + from_name = 'Example DMARC Report'; + msgid_from = 'rspamd.mail.example.com'; max_entries = 2k; keys_expire = 2d; -} -

      +}

      Create or modify docker-compose.override.yml in the mailcow-dockerized base directory:

      -
      version: '2.1'
      -
      -services:
      +

      ``` +version: '2.1'

      +

      services: rspamd-mailcow: environment: - MASTER=${MASTER:-y} labels: - ofelia.enabled: "true" - ofelia.job-exec.rspamd_dmarc_reporting.schedule: "@every 24h" - ofelia.job-exec.rspamd_dmarc_reporting.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/bin/rspamadm dmarc_report > /var/lib/rspamd/dmarc_reports_last_log 2>&1 || exit 0\"" + ofelia.enabled: "true" + ofelia.job-exec.rspamd_dmarc_reporting.schedule: "@every 24h" + ofelia.job-exec.rspamd_dmarc_reporting.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/bin/rspamadm dmarc_report > /var/lib/rspamd/dmarc_reports_last_log 2>&1 || exit 0\"" ofelia-mailcow: depends_on: - rspamd-mailcow -

      +```

      Run docker-compose up -d

      Send a copy reports to yourself

      To receive a hidden copy of reports generated by Rspamd you can set a bcc_addrs list in the reporting config section of data/conf/rspamd/local.d/dmarc.conf:

      -
      reporting {
      +

      reporting { enabled = true; - email = 'noreply-dmarc@example.com'; - bcc_addrs = ["noreply-dmarc@example.com","parsedmarc@example.com"]; -[...] -

      + email = 'noreply-dmarc@example.com'; + bcc_addrs = ["noreply-dmarc@example.com","parsedmarc@example.com"]; +[...]

      Rspamd will load changes in real time, so you won't need to restart the container at this point.

      This can be useful if you...

        @@ -2547,21 +2545,16 @@ services:

      Troubleshooting

      Check when the report schedule last ran:

      -
      docker-compose exec rspamd-mailcow date -r /var/lib/rspamd/dmarc_reports_last_log
      -
      +

      docker-compose exec rspamd-mailcow date -r /var/lib/rspamd/dmarc_reports_last_log

      See the latest report output:

      -
      docker-compose exec rspamd-mailcow cat /var/lib/rspamd/dmarc_reports_last_log
      -
      +

      docker-compose exec rspamd-mailcow cat /var/lib/rspamd/dmarc_reports_last_log

      Manually trigger a DMARC report:

      -
      docker-compose exec rspamd-mailcow rspamadm dmarc_report
      -
      +

      docker-compose exec rspamd-mailcow rspamadm dmarc_report

      Validate that Rspamd has recorded data in Redis: Change 20220428 to date which you interested in.

      -

      docker-compose exec redis-mailcow redis-cli SMEMBERS "dmarc_idx;20220428"
      -
      +

      docker-compose exec redis-mailcow redis-cli SMEMBERS "dmarc_idx;20220428" Take one of the lines from output you interested in and request it, f.e.: -

      docker-compose exec redis-mailcow redis-cli ZRANGE "dmarc_rpt;microsoft.com;mailto:d@rua.agari.com;20220428" 0 49
      -

      +docker-compose exec redis-mailcow redis-cli ZRANGE "dmarc_rpt;microsoft.com;mailto:d@rua.agari.com;20220428" 0 49

      Change DMARC reporting frequency

      In the example above reports are sent once every 24 hours.

      Olefia schedule has same implementation as cron in Go, supported syntax described at cron Documentation

      @@ -2709,7 +2702,7 @@ Take one of the lines from output you interested in and request it, f.e.: - + diff --git a/en/post_installation/firststeps-ip_bindings/index.html b/en/post_installation/firststeps-ip_bindings/index.html index 1d242a773..71153a5db 100644 --- a/en/post_installation/firststeps-ip_bindings/index.html +++ b/en/post_installation/firststeps-ip_bindings/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -530,10 +530,65 @@
    • + + For technical reasons, http bindings are a bit different from other service bindings. + + +
    • + +
    • + + You will find the following variables, separated by a bind address and its port: + + +
    • + +
    • + + Example: HTTP_BIND=1.2.3.4 + + +
    • + +
    • + + Other services are bound by using the following format: + + +
    • + +
    • + + SMTP_PORT=1.2.3.4:25 will bind SMTP to the IP 1.2.3.4 on port 25 + + +
    • + +
    • + + Important! Specifying an IPv4 address will skip all IPv6 bindings since Docker 20.x. + + +
    • + +
    • + + doveadm, SQL as well as Solr are bound to local ports only, please do not change that, unless you know what you are doing. + + + +
    • @@ -2410,10 +2465,65 @@
    • + + For technical reasons, http bindings are a bit different from other service bindings. + + +
    • + +
    • + + You will find the following variables, separated by a bind address and its port: + + +
    • + +
    • + + Example: HTTP_BIND=1.2.3.4 + + +
    • + +
    • + + Other services are bound by using the following format: + + +
    • + +
    • + + SMTP_PORT=1.2.3.4:25 will bind SMTP to the IP 1.2.3.4 on port 25 + + +
    • + +
    • + + Important! Specifying an IPv4 address will skip all IPv6 bindings since Docker 20.x. + + +
    • + +
    • + + doveadm, SQL as well as Solr are bound to local ports only, please do not change that, unless you know what you are doing. + + + +
    • @@ -2434,29 +2544,25 @@ -

      IP bindings

      -

      Warning

      Changing the binding does not affect source NAT. See SNAT for required steps.

      IPv4 binding

      To adjust one or multiple IPv4 bindings, open mailcow.conf and edit one, multiple or all variables as per your needs:

      -
      # For technical reasons, http bindings are a bit different from other service bindings.
      -# You will find the following variables, separated by a bind address and its port:
      -# Example: HTTP_BIND=1.2.3.4
      -
      -HTTP_PORT=80
      +

      ```

      +

      For technical reasons, http bindings are a bit different from other service bindings.

      +

      You will find the following variables, separated by a bind address and its port:

      +

      Example: HTTP_BIND=1.2.3.4

      +

      HTTP_PORT=80 HTTP_BIND= HTTPS_PORT=443 -HTTPS_BIND= - -# Other services are bound by using the following format: -# SMTP_PORT=1.2.3.4:25 will bind SMTP to the IP 1.2.3.4 on port 25 -# Important! Specifying an IPv4 address will skip all IPv6 bindings since Docker 20.x. -# doveadm, SQL as well as Solr are bound to local ports only, please do not change that, unless you know what you are doing. - -SMTP_PORT=25 +HTTPS_BIND=

      +

      Other services are bound by using the following format:

      +

      SMTP_PORT=1.2.3.4:25 will bind SMTP to the IP 1.2.3.4 on port 25

      +

      Important! Specifying an IPv4 address will skip all IPv6 bindings since Docker 20.x.

      +

      doveadm, SQL as well as Solr are bound to local ports only, please do not change that, unless you know what you are doing.

      +

      SMTP_PORT=25 SMTPS_PORT=465 SUBMISSION_PORT=587 IMAP_PORT=143 @@ -2467,35 +2573,36 @@ SIEVE_PORT=4190 DOVEADM_PORT=127.0.0.1:19991 SQL_PORT=127.0.0.1:13306 SOLR_PORT=127.0.0.1:18983 -

      +```

      To apply your changes, run docker-compose down followed by docker-compose up -d.

      IPv6 binding

      Changing IPv6 bindings is different from IPv4. Again, this has a technical background.

      A docker-compose.override.yml file will be used instead of editing the docker-compose.yml file directly. This is to maintain updatability, as the docker-compose.yml file gets updated regularly and your changes will most likely be overwritten.

      Edit to create a file docker-compose.override.yml with the following content. Its content will be merged with the productive docker-compose.yml file.

      An imaginary IPv6 2a00:dead:beef::abc is given. The first suffix :PORT1 defines the external port, while the second suffix :PORT2 routes to the corresponding port inside the container and must not be changed.

      -
      version: '2.1'
      -services:
      +

      ``` +version: '2.1' +services:

      +
      dovecot-mailcow:
      +  ports:
      +    - '2a00:dead:beef::abc:143:143'
      +    - '2a00:dead:beef::abc:993:993'
      +    - '2a00:dead:beef::abc:110:110'
      +    - '2a00:dead:beef::abc:995:995'
      +    - '2a00:dead:beef::abc:4190:4190'
       
      -    dovecot-mailcow:
      -      ports:
      -        - '2a00:dead:beef::abc:143:143'
      -        - '2a00:dead:beef::abc:993:993'
      -        - '2a00:dead:beef::abc:110:110'
      -        - '2a00:dead:beef::abc:995:995'
      -        - '2a00:dead:beef::abc:4190:4190'
      +postfix-mailcow:
      +  ports:
      +    - '2a00:dead:beef::abc:25:25'
      +    - '2a00:dead:beef::abc:465:465'
      +    - '2a00:dead:beef::abc:587:587'
       
      -    postfix-mailcow:
      -      ports:
      -        - '2a00:dead:beef::abc:25:25'
      -        - '2a00:dead:beef::abc:465:465'
      -        - '2a00:dead:beef::abc:587:587'
      -
      -    nginx-mailcow:
      -      ports:
      -        - '2a00:dead:beef::abc:80:80'
      -        - '2a00:dead:beef::abc:443:443'
      -
      +nginx-mailcow: + ports: + - '2a00:dead:beef::abc:80:80' + - '2a00:dead:beef::abc:443:443' + +

      ```

      To apply your changes, run docker-compose down followed by docker-compose up -d.


      @@ -2616,7 +2723,7 @@ services: - + diff --git a/en/post_installation/firststeps-local_mta/index.html b/en/post_installation/firststeps-local_mta/index.html index db1c67896..93200ee8b 100644 --- a/en/post_installation/firststeps-local_mta/index.html +++ b/en/post_installation/firststeps-local_mta/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,19 +2380,17 @@ -

      Local MTA on Docker host

      -

      The easiest option would be to disable the listener on port 25/tcp.

      Postfix users disable the listener by commenting the following line (starting with smtp or 25) in /etc/postfix/master.cf: -

      #smtp      inet  n       -       -       -       -       smtpd
      -

      +```

      +

      smtp inet n - - - - smtpd

      +

      ```

      Furthermore, to relay over a dockerized mailcow, you may want to add 172.22.1.1 as relayhost and remove the Docker interface from "inet_interfaces":

      -
      postconf -e 'relayhost = 172.22.1.1'
      -postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128"
      -postconf -e "inet_interfaces = loopback-only"
      -postconf -e "relay_transport = relay"
      -postconf -e "default_transport = smtp"
      -
      +

      postconf -e 'relayhost = 172.22.1.1' +postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128" +postconf -e "inet_interfaces = loopback-only" +postconf -e "relay_transport = relay" +postconf -e "default_transport = smtp"

      Now it is important to not have the same FQDN in myhostname as you use for your dockerized mailcow. Check your local (non-Docker) Postfix' main.cf for myhostname and set it to something different, for example local.my.fqdn.tld.

      "172.22.1.1" is the mailcow created network gateway in Docker. Relaying over this interface is necessary (instead of - for example - relaying directly over ${MAILCOW_HOSTNAME}) to relay over a known internal network.

      @@ -2507,7 +2514,7 @@ Relaying over this interface is necessary (instead of - for example - relaying d - + diff --git a/en/post_installation/firststeps-logging/index.html b/en/post_installation/firststeps-logging/index.html index 5c8393a11..497bede77 100644 --- a/en/post_installation/firststeps-logging/index.html +++ b/en/post_installation/firststeps-logging/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -572,6 +572,33 @@ + + + + + +
    • + + For Rsyslog only: + + +
    • + +
    • + + To move local3 input to /var/log/mailcow.log and stop processing, create a file "/etc/rsyslog.d/docker.conf": + + +
    • + +
    • + + Restart rsyslog afterwards. + + + + +
    • + +
    • + + For Rsyslog only: + + +
    • + +
    • + + To move local3 input to /var/log/mailcow.log and stop processing, create a file "/etc/rsyslog.d/docker.conf": + + +
    • + +
    • + + Restart rsyslog afterwards. + + +
    • + + !/bin/bash + + + +
    • @@ -2490,16 +2516,14 @@ -

      Reverse Proxy

      -

      You don't need to change the Nginx site that comes with mailcow: dockerized. mailcow: dockerized trusts the default gateway IP 172.22.1.1 as proxy.

      1. Make sure you change HTTP_BIND and HTTPS_BIND in mailcow.conf to a local address and set the ports accordingly, for example: -

      HTTP_BIND=127.0.0.1
      -HTTP_PORT=8080
      -HTTPS_BIND=127.0.0.1
      -HTTPS_PORT=8443
      -

      +bash +HTTP_BIND=127.0.0.1 +HTTP_PORT=8080 +HTTPS_BIND=127.0.0.1 +HTTPS_PORT=8443

      This will also change the bindings inside the Nginx container! This is important, if you decide to use a proxy within Docker.

      IMPORTANT: Do not use port 8081, 9081 or 65510!

      Recreate affected containers by running docker-compose up -d.

      @@ -2528,81 +2552,73 @@ On many servers logrotate will reload the webserver daily anyway.

      2. Configure your local webserver as reverse proxy:

      Apache 2.4

      Required modules: -

      a2enmod rewrite proxy proxy_http headers ssl
      -

      +a2enmod rewrite proxy proxy_http headers ssl

      Let's Encrypt will follow our rewrite, certificate requests in mailcow will work fine.

      Take care of highlighted lines.

      -
      <VirtualHost *:80>
      -  ServerName CHANGE_TO_MAILCOW_HOSTNAME
      -  ServerAlias autodiscover.*
      -  ServerAlias autoconfig.*
      -  RewriteEngine on
      -
      -  RewriteCond %{HTTPS} off
      -  RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R=301,L]
      -
      -  ProxyPass / http://127.0.0.1:8080/
      -  ProxyPassReverse / http://127.0.0.1:8080/
      -  ProxyPreserveHost On
      -  ProxyAddHeaders On
      -  RequestHeader set X-Forwarded-Proto "http"
      -</VirtualHost>
      -<VirtualHost *:443>
      -  ServerName CHANGE_TO_MAILCOW_HOSTNAME
      -  ServerAlias autodiscover.*
      -  ServerAlias autoconfig.*
      -
      -  # You should proxy to a plain HTTP session to offload SSL processing
      -  ProxyPass /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync connectiontimeout=4000
      -  ProxyPassReverse /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync
      -  ProxyPass / http://127.0.0.1:8080/
      -  ProxyPassReverse / http://127.0.0.1:8080/
      -  ProxyPreserveHost On
      -  ProxyAddHeaders On
      -  RequestHeader set X-Forwarded-Proto "https"
      -
      -  SSLCertificateFile MAILCOW_PATH/data/assets/ssl/cert.pem
      -  SSLCertificateKeyFile MAILCOW_PATH/data/assets/ssl/key.pem
      -
      -  # If you plan to proxy to a HTTPS host:
      -  #SSLProxyEngine On
      -
      -  # If you plan to proxy to an untrusted HTTPS host:
      -  #SSLProxyVerify none
      -  #SSLProxyCheckPeerCN off
      -  #SSLProxyCheckPeerName off
      -  #SSLProxyCheckPeerExpire off
      -</VirtualHost>
      -
      +

      ``` apache hl_lines="2 10 11 17 22 23 24 25 30 31" + + ServerName CHANGE_TO_MAILCOW_HOSTNAME + ServerAlias autodiscover.* + ServerAlias autoconfig.* + RewriteEngine on

      +

      RewriteCond %{HTTPS} off + RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R=301,L]

      +

      ProxyPass / http://127.0.0.1:8080/ + ProxyPassReverse / http://127.0.0.1:8080/ + ProxyPreserveHost On + ProxyAddHeaders On + RequestHeader set X-Forwarded-Proto "http" + + + ServerName CHANGE_TO_MAILCOW_HOSTNAME + ServerAlias autodiscover.* + ServerAlias autoconfig.*

      +

      # You should proxy to a plain HTTP session to offload SSL processing + ProxyPass /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync connectiontimeout=4000 + ProxyPassReverse /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync + ProxyPass / http://127.0.0.1:8080/ + ProxyPassReverse / http://127.0.0.1:8080/ + ProxyPreserveHost On + ProxyAddHeaders On + RequestHeader set X-Forwarded-Proto "https"

      +

      SSLCertificateFile MAILCOW_PATH/data/assets/ssl/cert.pem + SSLCertificateKeyFile MAILCOW_PATH/data/assets/ssl/key.pem

      +

      # If you plan to proxy to a HTTPS host: + #SSLProxyEngine On

      +

      # If you plan to proxy to an untrusted HTTPS host: + #SSLProxyVerify none + #SSLProxyCheckPeerCN off + #SSLProxyCheckPeerName off + #SSLProxyCheckPeerExpire off + +```

      Nginx

      Let's Encrypt will follow our rewrite, certificate requests will work fine.

      Take care of highlighted lines.

      -
      server {
      +

      ``` hl_lines="4 10 12 13 25 39" +server { listen 80 default_server; listen [::]:80 default_server; - server_name CHANGE_TO_MAILCOW_HOSTNAME autodiscover.* autoconfig.*; - return 301 https://$host$request_uri; + server_name CHANGE_TO_MAILCOW_HOSTNAME autodiscover.* autoconfig.; + return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; - server_name CHANGE_TO_MAILCOW_HOSTNAME autodiscover.* autoconfig.*; - - ssl_certificate MAILCOW_PATH/data/assets/ssl/cert.pem; - ssl_certificate_key MAILCOW_PATH/data/assets/ssl/key.pem; - ssl_session_timeout 1d; + server_name CHANGE_TO_MAILCOW_HOSTNAME autodiscover. autoconfig.*;

      +

      ssl_certificate MAILCOW_PATH/data/assets/ssl/cert.pem; + ssl_certificate_key MAILCOW_PATH/data/assets/ssl/key.pem; + ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; - ssl_session_tickets off; - - # See https://ssl-config.mozilla.org/#server=nginx for the latest ssl settings recommendations + ssl_session_tickets off;

      +

      # See https://ssl-config.mozilla.org/#server=nginx for the latest ssl settings recommendations # An example config is given below ssl_protocols TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5:!SHA1:!kRSA; - ssl_prefer_server_ciphers off; - - location /Microsoft-Server-ActiveSync { - proxy_pass http://127.0.0.1:8080/Microsoft-Server-ActiveSync; - proxy_set_header Host $http_host; + ssl_prefer_server_ciphers off;

      +

      location /Microsoft-Server-ActiveSync { + proxy_pass http://127.0.0.1:8080/Microsoft-Server-ActiveSync; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; @@ -2612,39 +2628,38 @@ server { proxy_buffers 64 512k; # Needed since the 2022-04 Update for SOGo client_body_buffer_size 512k; client_max_body_size 0; - } - - location / { - proxy_pass http://127.0.0.1:8080/; - proxy_set_header Host $http_host; + }

      +

      location / { + proxy_pass http://127.0.0.1:8080/; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 0; # The following Proxy Buffers has to be set if you want to use SOGo after the 2022-04 (April 2022) Update - # Otherwise a Login will fail like this: https://github.com/mailcow/mailcow-dockerized/issues/4537 + # Otherwise a Login will fail like this: https://github.com/mailcow/mailcow-dockerized/issues/4537 proxy_buffer_size 128k; proxy_buffers 64 512k; proxy_busy_buffers_size 512k; } } -

      +```

      HAProxy (community supported)

      Warning

      This is an unsupported community contribution. Feel free to provide fixes.

      Important/Fixme: This example only forwards HTTPS traffic and does not use mailcows built-in ACME client.

      -
      frontend https-in
      +

      ``` +frontend https-in bind :::443 v4v6 ssl crt mailcow.pem - default_backend mailcow - -backend mailcow + default_backend mailcow

      +

      backend mailcow option forwardfor http-request set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Proto http if !{ ssl_fc } server mailcow 127.0.0.1:8080 check -

      +```

      Traefik v2 (community supported)

      Warning

      @@ -2655,50 +2670,49 @@ backend mailcow

      So, first of all, we are going to disable the acme-mailcow container since we'll use the certs that traefik will provide us. For this we'll have to set SKIP_LETS_ENCRYPT=y on our mailcow.conf, and run docker-compose up -d to apply the changes.

      Then we'll create a docker-compose.override.yml file in order to override the main docker-compose.yml found in your mailcow root folder.

      -
      version: '2.1'
      -
      -services:
      -    nginx-mailcow:
      -      networks:
      -        # add Traefik's network
      -        web:
      -      labels:
      -        - traefik.enable=true
      -        # Creates a router called "moo" for the container, and sets up a rule to link the container to certain rule,
      -        #   in this case, a Host rule with our MAILCOW_HOSTNAME var.
      -        - traefik.http.routers.moo.rule=Host(`${MAILCOW_HOSTNAME}`)
      -        # Enables tls over the router we created before.
      -        - traefik.http.routers.moo.tls=true
      -        # Specifies which kind of cert resolver we'll use, in this case le (Lets Encrypt).
      -        - traefik.http.routers.moo.tls.certresolver=le
      -        # Creates a service called "moo" for the container, and specifies which internal port of the container
      -        #   should traefik route the incoming data to.
      -        - traefik.http.services.moo.loadbalancer.server.port=${HTTP_PORT}
      -        # Specifies which entrypoint (external port) should traefik listen to, for this container.
      -        #   websecure being port 443, check the traefik.toml file liked above.
      -        - traefik.http.routers.moo.entrypoints=websecure
      -        # Make sure traefik uses the web network, not the mailcowdockerized_mailcow-network
      -        - traefik.docker.network=web
      -
      -    certdumper:
      -        image: humenius/traefik-certs-dumper
      -        container_name: traefik_certdumper
      -        network_mode: none
      -        volumes:
      -          # mount the folder which contains Traefik's `acme.json' file
      -          #   in this case Traefik is started from its own docker-compose in ../traefik
      -          - ../traefik/data:/traefik:ro
      -          # mount mailcow's SSL folder
      -          - ./data/assets/ssl/:/output:rw
      -        restart: always
      -        environment:
      -          # only change this, if you're using another domain for mailcow's web frontend compared to the standard config
      -          - DOMAIN=${MAILCOW_HOSTNAME}
      -
      -networks:
      -  web:
      -    external: true
      -
      +

      ```yaml +version: '2.1'

      +

      services: + nginx-mailcow: + networks: + # add Traefik's network + web: + labels: + - traefik.enable=true + # Creates a router called "moo" for the container, and sets up a rule to link the container to certain rule, + # in this case, a Host rule with our MAILCOW_HOSTNAME var. + - traefik.http.routers.moo.rule=Host(${MAILCOW_HOSTNAME}) + # Enables tls over the router we created before. + - traefik.http.routers.moo.tls=true + # Specifies which kind of cert resolver we'll use, in this case le (Lets Encrypt). + - traefik.http.routers.moo.tls.certresolver=le + # Creates a service called "moo" for the container, and specifies which internal port of the container + # should traefik route the incoming data to. + - traefik.http.services.moo.loadbalancer.server.port=${HTTP_PORT} + # Specifies which entrypoint (external port) should traefik listen to, for this container. + # websecure being port 443, check the traefik.toml file liked above. + - traefik.http.routers.moo.entrypoints=websecure + # Make sure traefik uses the web network, not the mailcowdockerized_mailcow-network + - traefik.docker.network=web

      +
      certdumper:
      +    image: humenius/traefik-certs-dumper
      +    container_name: traefik_certdumper
      +    network_mode: none
      +    volumes:
      +      # mount the folder which contains Traefik's `acme.json' file
      +      #   in this case Traefik is started from its own docker-compose in ../traefik
      +      - ../traefik/data:/traefik:ro
      +      # mount mailcow's SSL folder
      +      - ./data/assets/ssl/:/output:rw
      +    restart: always
      +    environment:
      +      # only change this, if you're using another domain for mailcow's web frontend compared to the standard config
      +      - DOMAIN=${MAILCOW_HOSTNAME}
      +
      +

      networks: + web: + external: true +```

      Start the new containers with docker-compose up -d.

      Now, there's only one thing left to do, which is setup the certs so that the mail services can use them as well, since Traefik 2 uses an acme v2 format to save ALL the license from all the domains we have, we'll need to find a way to dump the certs, lucky we have this tiny container which grabs the acme.json file trough a volume, and a variable DOMAIN=example.org, and with these, the container will output the cert.pem and key.pem files, for this we'll simply run the traefik-certs-dumper container binding the /traefik volume to the folder where our acme.json is saved, bind the /output volume to our mailcow data/assets/ssl/ folder, and set up the DOMAIN=example.org variable to the domain we want the certs dumped from.

      This container will watch over the acme.json file for any changes, and regenerate the cert.pem and key.pem files directly into data/assets/ssl/ being the path binded to the container's /output path.

      @@ -2708,18 +2722,18 @@ For this we'll have to set SKIP_LETS_ENCRYPT=y on our mailcow

      Optional: Post-hook script for non-mailcow ACME clients

      Using a local certbot (or any other ACME client) requires to restart some containers, you can do this with a post-hook script. Make sure you change the paths accordingly: -

      #!/bin/bash
      -cp /etc/letsencrypt/live/my.domain.tld/fullchain.pem /opt/mailcow-dockerized/data/assets/ssl/cert.pem
      +```

      +

      !/bin/bash

      +

      cp /etc/letsencrypt/live/my.domain.tld/fullchain.pem /opt/mailcow-dockerized/data/assets/ssl/cert.pem cp /etc/letsencrypt/live/my.domain.tld/privkey.pem /opt/mailcow-dockerized/data/assets/ssl/key.pem postfix_c=$(docker ps -qaf name=postfix-mailcow) dovecot_c=$(docker ps -qaf name=dovecot-mailcow) nginx_c=$(docker ps -qaf name=nginx-mailcow) docker restart ${postfix_c} ${dovecot_c} ${nginx_c} -

      +```

      Adding additional server names for mailcow UI

      If you plan to use a server name that is not MAILCOW_HOSTNAME in your reverse proxy, make sure to populate that name in mailcow.conf via ADDITIONAL_SERVER_NAMES first. Names must be separated by commas and must not contain spaces. If you skip this step, mailcow may respond to your reverse proxy with an incorrect site.

      -
      ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld
      -
      +

      ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld

      Run docker-compose up -d to apply.


      @@ -2840,7 +2854,7 @@ docker restart ${postfix_c} ${dovecot_c} ${nginx_c} - + diff --git a/en/post_installation/firststeps-rspamd_ui/index.html b/en/post_installation/firststeps-rspamd_ui/index.html index 82d3a0655..af80c22d6 100644 --- a/en/post_installation/firststeps-rspamd_ui/index.html +++ b/en/post_installation/firststeps-rspamd_ui/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2500,7 +2500,7 @@ - + diff --git a/en/post_installation/firststeps-snat/index.html b/en/post_installation/firststeps-snat/index.html index 91d537b24..ae755ae4d 100644 --- a/en/post_installation/firststeps-snat/index.html +++ b/en/post_installation/firststeps-snat/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@
      @@ -564,6 +569,8 @@ + + SNAT @@ -2354,6 +2361,8 @@ + +
      @@ -2371,17 +2380,15 @@ -

      SNAT

      -

      SNAT is used to change the source address of the packets sent by mailcow. It can be used to change the outgoing IP address on systems with multiple IP addresses.

      Open mailcow.conf, set either or both of the following parameters:

      -
      # Use this IPv4 for outgoing connections (SNAT)
      -SNAT_TO_SOURCE=1.2.3.4
      -
      -# Use this IPv6 for outgoing connections (SNAT)
      -SNAT6_TO_SOURCE=dead:beef
      -
      +

      ```

      +

      Use this IPv4 for outgoing connections (SNAT)

      +

      SNAT_TO_SOURCE=1.2.3.4

      +

      Use this IPv6 for outgoing connections (SNAT)

      +

      SNAT6_TO_SOURCE=dead:beef +```

      Run docker-compose up -d.

      The values are read by netfilter-mailcow. netfilter-mailcow will make sure, the post-routing rules are on position 1 in the netfilter table. It does automatically delete and re-create them if they are found on another position than 1.

      Check the output of docker-compose logs --tail=200 netfilter-mailcow to ensure the SNAT settings have been applied.

      @@ -2504,7 +2511,7 @@ SNAT6_TO_SOURCE=dead:beef - + diff --git a/en/post_installation/firststeps-ssl/index.html b/en/post_installation/firststeps-ssl/index.html index af40d79ae..2842f198f 100644 --- a/en/post_installation/firststeps-ssl/index.html +++ b/en/post_installation/firststeps-ssl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -502,6 +502,19 @@ + + + + + +
    • + + Now check the logs for a renewal + + + +
    • + +
    • + + Connect via SMTP (587) + + +
    • + +
    • + + Connect via IMAP (143) + + +
    • + +
    • + + Connect via HTTPS (443) + +
    • @@ -2506,6 +2540,19 @@ + + + + + +
    • + + Now check the logs for a renewal + + + +
    • + +
    • + + Connect via SMTP (587) + + +
    • + +
    • + + Connect via IMAP (143) + + +
    • + +
    • + + Connect via HTTPS (443) + +
    • @@ -2598,8 +2666,6 @@ -

      Advanced SSL

      -

      Let's Encrypt (out-of-the-box)

      The "acme-mailcow" container will try to obtain a LE certificate for ${MAILCOW_HOSTNAME}, autodiscover.ADDED_MAIL_DOMAIN and autoconfig.ADDED_MAIL_DOMAIN.

      @@ -2614,8 +2680,7 @@

      Additional domain names

      Edit "mailcow.conf" and add a parameter ADDITIONAL_SAN like this:

      Do not use quotes (") and do not use spaces between the names!

      -
      ADDITIONAL_SAN=smtp.*,cert1.example.com,cert2.example.org,whatever.*
      -
      +

      ADDITIONAL_SAN=smtp.*,cert1.example.com,cert2.example.org,whatever.*

      Each name will be validated against its IPv6 address or - if IPv6 is not configured in your domain - IPv4 address.

      A wildcard name like smtp.* will try to obtain a smtp.DOMAIN_NAME SAN for each domain added to mailcow.

      Run docker-compose up -d to recreate affected containers automatically.

      @@ -2624,17 +2689,17 @@

      Using names other name MAILCOW_HOSTNAME to access the mailcow UI may need further configuration.

      If you plan to use a server name that is not MAILCOW_HOSTNAME to access the mailcow UI (for example by adding mail.* to ADDITIONAL_SAN make sure to populate that name in mailcow.conf via ADDITIONAL_SERVER_NAMES. Names must be separated by commas and must not contain spaces. If you skip this step, mailcow may respond with an incorrect site.

      -
      ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld
      -
      +

      ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld

      Run docker-compose up -d to apply.

      Force renewal

      To force a renewal, you need to create a file named force_renew and restart the acme-mailcow container:

      -
      cd /opt/mailcow-dockerized
      +

      ``` +cd /opt/mailcow-dockerized touch data/assets/ssl/force_renew -docker-compose restart acme-mailcow -# Now check the logs for a renewal -docker-compose logs --tail=200 -f acme-mailcow -

      +docker-compose restart acme-mailcow

      +

      Now check the logs for a renewal

      +

      docker-compose logs --tail=200 -f acme-mailcow +```

      The file will be deleted automatically.

      Validation errors and how to skip validation

      You can skip the IP verification by setting SKIP_IP_CHECK=y in mailcow.conf (no quotes). Be warned that a misconfiguration will get you ratelimited by Let's Encrypt! This is primarily useful for multi-IP setups where the IP check would return the incorrect source IP address. Due to using dynamic IPs for acme-mailcow, source NAT is not consistent over restarts.

      @@ -2681,35 +2746,33 @@ You should make sure these clients use the MAILCOW_HOSTNAME for sec

      To use your own certificates, just save the combined certificate (containing the certificate and intermediate CA/CA if any) to data/assets/ssl/cert.pem and the corresponding key to data/assets/ssl/key.pem.

      IMPORTANT: Do not use symbolic links! Make sure you copy the certificates and do not link them to data/assets/ssl.

      Restart affected services afterwards:

      -
      docker restart $(docker ps -qaf name=postfix-mailcow)
      +

      docker restart $(docker ps -qaf name=postfix-mailcow) docker restart $(docker ps -qaf name=nginx-mailcow) -docker restart $(docker ps -qaf name=dovecot-mailcow) -

      +docker restart $(docker ps -qaf name=dovecot-mailcow)

      See Post-hook script for non-mailcow ACME clients for a full example script.

      Test against staging ACME directory

      Edit mailcow.conf and add LE_STAGING=y.

      Run docker-compose up -d to activate your changes.

      Custom directory URL

      Edit mailcow.conf and add the corresponding directory URL to the new variable DIRECTORY_URL:

      -
      DIRECTORY_URL=https://acme-custom-v9000.api.letsencrypt.org/directory
      -
      +

      DIRECTORY_URL=https://acme-custom-v9000.api.letsencrypt.org/directory

      You cannot use LE_STAGING with DIRECTORY_URL. If both are set, only LE_STAGING is used.

      Run docker-compose up -d to activate your changes.

      Check your configuration

      Run docker-compose logs acme-mailcow to find out why a validation fails.

      To check if nginx serves the correct certificate, simply use a browser of your choice and check the displayed certificate.

      To check the certificate served by Postfix, Dovecot and Nginx we will use openssl:

      -
      # Connect via SMTP (587)
      -echo "Q" | openssl s_client -starttls smtp -crlf -connect mx.mailcow.email:587
      -# Connect via IMAP (143)
      -echo "Q" | openssl s_client -starttls imap -showcerts -connect mx.mailcow.email:143
      -# Connect via HTTPS (443)
      -echo "Q" | openssl s_client -connect mx.mailcow.email:443
      -
      +

      ```

      +

      Connect via SMTP (587)

      +

      echo "Q" | openssl s_client -starttls smtp -crlf -connect mx.mailcow.email:587

      +

      Connect via IMAP (143)

      +

      echo "Q" | openssl s_client -starttls imap -showcerts -connect mx.mailcow.email:143

      +

      Connect via HTTPS (443)

      +

      echo "Q" | openssl s_client -connect mx.mailcow.email:443 +```

      To validate the expiry dates as returned by openssl against MAILCOW_HOSTNAME, you are able to use our helper script:

      -
      cd /opt/mailcow-dockerized
      -bash helper-scripts/expiry-dates.sh
      -
      +

      cd /opt/mailcow-dockerized +bash helper-scripts/expiry-dates.sh


      @@ -2829,7 +2892,7 @@ bash helper-scripts/expiry-dates.sh - + diff --git a/en/post_installation/firststeps-sync_jobs_migration/index.html b/en/post_installation/firststeps-sync_jobs_migration/index.html index e5d55dedd..7f8fd5e06 100644 --- a/en/post_installation/firststeps-sync_jobs_migration/index.html +++ b/en/post_installation/firststeps-sync_jobs_migration/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2574,7 +2574,7 @@ - + diff --git a/en/prerequisite/prerequisite-dns/index.html b/en/prerequisite/prerequisite-dns/index.html index f5499effa..710d57231 100644 --- a/en/prerequisite/prerequisite-dns/index.html +++ b/en/prerequisite/prerequisite-dns/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -364,27 +364,75 @@
    • + + Name Type Value + + + +
    • + + Name Type Value + + +
    • + +
    • + + Name Type Value + + +
    • + +
    • + + Name Type Value + + + +
    • + + Name Type Priority Weight Port Value + + + + +
    • + + + + + + +
    • + + ``` + + +
    • + +
    • + + Summary of Results + + + + +
    • + +
    • + + ``` + + +
    • + +
    • + + Summary of Results + + +
    • @@ -2371,45 +2380,43 @@ -

      Gitea

      -

      With Gitea' ability to authenticate over SMTP it is trivial to integrate it with mailcow. Few changes are needed:

      1. Open docker-compose.override.yml and add gitea:

      -
      version: '2.1'
      -services:
      -
      -        gitea-mailcow:
      -            image: gitea/gitea:1
      -            volumes:
      -                - ./data/gitea:/data
      -            networks:
      -                mailcow-network:
      -                    aliases:
      -                        - gitea
      -            ports:
      -                - "${GITEA_SSH_PORT:-127.0.0.1:4000}:22"
      -
      +

      ``` +version: '2.1' +services:

      +
          gitea-mailcow:
      +        image: gitea/gitea:1
      +        volumes:
      +            - ./data/gitea:/data
      +        networks:
      +            mailcow-network:
      +                aliases:
      +                    - gitea
      +        ports:
      +            - "${GITEA_SSH_PORT:-127.0.0.1:4000}:22"
      +
      +

      ```

      2. Create data/conf/nginx/site.gitea.custom, add: -

      location /gitea/ {
      +location /gitea/ {
               proxy_pass http://gitea:3000/;
      -}
      -

      +}

      3. Open mailcow.conf and define the binding you want gitea to use for SSH. Example:

      -
      GITEA_SSH_PORT=127.0.0.1:4000
      -
      +

      GITEA_SSH_PORT=127.0.0.1:4000

      5. Run docker-compose up -d to bring up the gitea container and run docker-compose restart nginx-mailcow afterwards.

      6. If you forced mailcow to https, execute step 9 and restart gitea with docker-compose restart gitea-mailcow . Go head with step 7 (Remember to use https instead of http, https://mx.example.org/gitea/

      7. Open http://${MAILCOW_HOSTNAME}/gitea/, for example http://mx.example.org/gitea/. For database details set mysql as database host. Use the value of DBNAME found in mailcow.conf as database name, DBUSER as database user and DBPASS as database password.

      8. Once the installation is complete, login as admin and set "settings" -> "authorization" -> "enable SMTP". SMTP Host should be postfix with port 587, set Skip TLS Verify as we are using an unlisted SAN ("postfix" is most likely not part of your certificate).

      9. Create data/gitea/gitea/conf/app.ini and set following values. You can consult gitea cheat sheet for their meaning and other possible values.

      -
      [server]
      -SSH_LISTEN_PORT = 22
      -# For GITEA_SSH_PORT=127.0.0.1:4000 in mailcow.conf, set:
      -SSH_DOMAIN = 127.0.0.1
      -SSH_PORT = 4000
      -# For MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (and default ports for HTTPS), set:
      -ROOT_URL = https://mx.example.org/gitea/
      -
      +

      ``` +[server] +SSH_LISTEN_PORT = 22

      +

      For GITEA_SSH_PORT=127.0.0.1:4000 in mailcow.conf, set:

      +

      SSH_DOMAIN = 127.0.0.1 +SSH_PORT = 4000

      +

      For MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (and default ports for HTTPS), set:

      +

      ROOT_URL = https://mx.example.org/gitea/ +```

      10. Restart gitea with docker-compose restart gitea-mailcow. Your users should be able to login with mailcow managed accounts.


      @@ -2530,7 +2537,7 @@ ROOT_URL = https://mx.example.org/gitea/ - + diff --git a/en/third_party/third_party-gogs/index.html b/en/third_party/third_party-gogs/index.html index a0b18db18..d73d71053 100644 --- a/en/third_party/third_party-gogs/index.html +++ b/en/third_party/third_party-gogs/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@
      @@ -2251,6 +2256,8 @@ + + Gogs @@ -2354,6 +2361,8 @@ + +
      @@ -2371,44 +2380,42 @@ -

      Gogs

      -

      With Gogs' ability to authenticate over SMTP it is trivial to integrate it with mailcow. Few changes are needed:

      1. Open docker-compose.override.yml and add Gogs:

      -
      version: '2.1'
      -services:
      -
      -    gogs-mailcow:
      -      image: gogs/gogs
      -      volumes:
      -        - ./data/gogs:/data
      -      networks:
      -        mailcow-network:
      -          aliases:
      -            - gogs
      -      ports:
      -        - "${GOGS_SSH_PORT:-127.0.0.1:4000}:22"
      -
      +

      ``` +version: '2.1' +services:

      +
      gogs-mailcow:
      +  image: gogs/gogs
      +  volumes:
      +    - ./data/gogs:/data
      +  networks:
      +    mailcow-network:
      +      aliases:
      +        - gogs
      +  ports:
      +    - "${GOGS_SSH_PORT:-127.0.0.1:4000}:22"
      +
      +

      ```

      2. Create data/conf/nginx/site.gogs.custom, add: -

      location /gogs/ {
      +location /gogs/ {
           proxy_pass http://gogs:3000/;
      -}
      -

      +}

      3. Open mailcow.conf and define the binding you want Gogs to use for SSH. Example:

      -
      GOGS_SSH_PORT=127.0.0.1:4000
      -
      +

      GOGS_SSH_PORT=127.0.0.1:4000

      5. Run docker-compose up -d to bring up the Gogs container and run docker-compose restart nginx-mailcow afterwards.

      6. Open http://${MAILCOW_HOSTNAME}/gogs/, for example http://mx.example.org/gogs/. For database details set mysql as database host. Use the value of DBNAME found in mailcow.conf as database name, DBUSER as database user and DBPASS as database password.

      7. Once the installation is complete, login as admin and set "settings" -> "authorization" -> "enable SMTP". SMTP Host should be postfix with port 587, set Skip TLS Verify as we are using an unlisted SAN ("postfix" is most likely not part of your certificate).

      8. Create data/gogs/gogs/conf/app.ini and set following values. You can consult Gogs cheat sheet for their meaning and other possible values.

      -
      [server]
      -SSH_LISTEN_PORT = 22
      -# For GOGS_SSH_PORT=127.0.0.1:4000 in mailcow.conf, set:
      -SSH_DOMAIN = 127.0.0.1
      -SSH_PORT = 4000
      -# For MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (and default ports for HTTPS), set:
      -ROOT_URL = https://mx.example.org/gogs/
      -
      +

      ``` +[server] +SSH_LISTEN_PORT = 22

      +

      For GOGS_SSH_PORT=127.0.0.1:4000 in mailcow.conf, set:

      +

      SSH_DOMAIN = 127.0.0.1 +SSH_PORT = 4000

      +

      For MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (and default ports for HTTPS), set:

      +

      ROOT_URL = https://mx.example.org/gogs/ +```

      9. Restart Gogs with docker-compose restart gogs-mailcow. Your users should be able to login with mailcow managed accounts.


      @@ -2529,7 +2536,7 @@ ROOT_URL = https://mx.example.org/gogs/ - + diff --git a/en/third_party/third_party-mailman3/index.html b/en/third_party/third_party-mailman3/index.html index 8189cba56..3b8c2bb39 100644 --- a/en/third_party/third_party-mailman3/index.html +++ b/en/third_party/third_party-mailman3/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2317,162 +2317,6 @@ DNS setup - - -
    • - - Install Apache as a reverse proxy - - - - -
    • - -
    • - - Obtain SSL certificates with Let's Encrypt - - -
    • - -
    • - - Install mailcow with Mailman integration - - - - -
    • - -
    • - - Install Mailman - - - - -
    • - -
    • - - 🏃 Run - - -
    • - - - - - - -
    • - - Remarks - - - - -
    • - -
    • - - Update - - -
    • - -
    • - - Backup - - -
    • - -
    • - - ToDo - - -
    • - -
    • - - Install Apache as a reverse proxy - - - - -
    • - -
    • - - Obtain SSL certificates with Let's Encrypt - - -
    • - -
    • - - Install mailcow with Mailman integration - - - - -
    • - -
    • - - Install Mailman - - - - -
    • - -
    • - - 🏃 Run - - -
    • - - - - - - -
    • - - Remarks - - - - -
    • - -
    • - - Update - - -
    • - -
    • - - Backup - - -
    • - -
    • - - ToDo - - -
    • The problem to solve

      mailpiler offers the authentication based on IMAP, for example:

      -
      $config['ENABLE_IMAP_AUTH'] = 1;
      -$config['IMAP_HOST'] = 'mail.example.com';
      -$config['IMAP_PORT'] =  993;
      -$config['IMAP_SSL'] = true;
      -
      +

      php +$config['ENABLE_IMAP_AUTH'] = 1; +$config['IMAP_HOST'] = 'mail.example.com'; +$config['IMAP_PORT'] = 993; +$config['IMAP_SSL'] = true;

      • So when you log in using patrik@example.com, you will only see delivered emails sent from or to this specific email address.
      • When additional aliases are defined in mailcow, like team@example.com, you won't see emails sent to or from this email address even the fact you're a recipient of mails sent to this alias address.
      • @@ -2515,19 +2515,19 @@
        1. Set the custom query function of mailpiler and append this to /usr/local/etc/piler/config-site.php:

          -
          $config['MAILCOW_API_KEY'] = 'YOUR_READONLY_API_KEY';
          -$config['MAILCOW_SET_REALNAME'] = true; // when not specified, then default is false
          -$config['CUSTOM_EMAIL_QUERY_FUNCTION'] = 'query_mailcow_for_email_access';
          -include('auth-mailcow.php');
          -
          +

          php +$config['MAILCOW_API_KEY'] = 'YOUR_READONLY_API_KEY'; +$config['MAILCOW_SET_REALNAME'] = true; // when not specified, then default is false +$config['CUSTOM_EMAIL_QUERY_FUNCTION'] = 'query_mailcow_for_email_access'; +include('auth-mailcow.php');

          You can also change the mailcow hostname, if required: -

          $config['MAILCOW_HOST'] = 'mail.domain.tld'; // defaults to $config['IMAP_HOST']
          -

          +php +$config['MAILCOW_HOST'] = 'mail.domain.tld'; // defaults to $config['IMAP_HOST']

        2. Download the PHP file with the functions from the GitHub repo:

          -
          curl -o /usr/local/etc/piler/auth-mailcow.php https://raw.githubusercontent.com/patschi/mailpiler-mailcow-integration/master/auth-mailcow.php
          -
          +

          sh +curl -o /usr/local/etc/piler/auth-mailcow.php https://raw.githubusercontent.com/patschi/mailpiler-mailcow-integration/master/auth-mailcow.php

        3. Done!

          @@ -2654,7 +2654,7 @@ - + diff --git a/en/third_party/third_party-nextcloud/index.html b/en/third_party/third_party-nextcloud/index.html index 567b4222a..cbe720d6f 100644 --- a/en/third_party/third_party-nextcloud/index.html +++ b/en/third_party/third_party-nextcloud/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2485,14 +2485,13 @@

          In order for mailcow to generate a a certificate for the nextcloud domain you need to add "nextcloud.domain.tld" to ADDITIONAL_SAN in mailcow.conf and run docker-compose up -d to apply. For more informaton refer to: Advanced SSL.

          Background jobs

          To use the recommended setting (cron) to execute the background jobs following lines need to be added to the docker-compose.override.yml:

          -
          version: '2.1'
          +

          version: '2.1' services: php-fpm-mailcow: labels: - ofelia.enabled: "true" - ofelia.job-exec.nextcloud-cron.schedule: "@every 5m" - ofelia.job-exec.nextcloud-cron.command: "su www-data -s /bin/bash -c \"/usr/local/bin/php -f /web/nextcloud/cron.php\"" -

          + ofelia.enabled: "true" + ofelia.job-exec.nextcloud-cron.schedule: "@every 5m" + ofelia.job-exec.nextcloud-cron.command: "su www-data -s /bin/bash -c \"/usr/local/bin/php -f /web/nextcloud/cron.php\""

          After adding these lines the docker-compose up -d command must be executed to update the docker image and also the docker scheduler image must be restarted to pick up the new job definition by executing docker-compose restart ofelia-mailcow. To check if the job was successfully picked up by ofelia the command docker-compose logs ofelia-mailcow will contain a line similar to New job registered "nextcloud-cron" - ....

          @@ -2544,14 +2543,12 @@ services:

          If you have previously used Nextcloud with mailcow authentication via user_external/IMAP, you need to perform some additional steps to link your existing user accounts with OAuth2.

          1. Click the button in the top right corner and select Apps. Scroll down to the External user authentication app and click Remove next to it. 2. Run the following queries in your Nextcloud database (if you set up Nextcloud using mailcow's script, you can run source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME): -

          INSERT INTO nc_users (uid, uid_lower) SELECT DISTINCT uid, LOWER(uid) FROM nc_users_external;
          -INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users_external;
          -

          +INSERT INTO nc_users (uid, uid_lower) SELECT DISTINCT uid, LOWER(uid) FROM nc_users_external; +INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users_external;


          If you have previously used Nextcloud without mailcow authentication, but with the same usernames as mailcow, you can also link your existing user accounts with OAuth2.

          1. Run the following queries in your Nextcloud database (if you set up Nextcloud using mailcow's script, you can run source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME): -

          INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users;
          -

          +INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users;


          Update

          The Nextcloud instance can be updated easily with the web update mechanism. In the case of larger updates, there may be further changes to be made after the update. After the Nextcloud instance has been checked, problems are shown. This can be e.g. missing indices in the DB or similar. @@ -2561,13 +2558,12 @@ It shows which commands have to be executed, these have to be placed in the php-


          Debugging & Troubleshooting

          It may happen that you cannot reach the Nextcloud instance from your network. This may be due to the fact that the entry of your subnet in the array 'trusted_proxies' is missing. You can make changes in the Nextcloud config.php in data/web/nextcloud/config/*.

          -
          'trusted_proxies' =>
          +

          'trusted_proxies' => array ( - 0 => 'fd4d:6169:6c63:6f77::/64', - 1 => '172.22.1.0/24', - 2 => 'NewSubnet/24', - ), -

          + 0 => 'fd4d:6169:6c63:6f77::/64', + 1 => '172.22.1.0/24', + 2 => 'NewSubnet/24', + ),

          After the changes have been made, the nginx container must be restarted. docker-compose restart nginx-mailcow

          @@ -2689,7 +2685,7 @@ It shows which commands have to be executed, these have to be placed in the php- - + diff --git a/en/third_party/third_party-portainer/index.html b/en/third_party/third_party-portainer/index.html index 85b99a483..cc4ecf735 100644 --- a/en/third_party/third_party-portainer/index.html +++ b/en/third_party/third_party-portainer/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2375,7 +2375,7 @@

          In order to enable Portainer, the docker-compose.yml and site.conf for Nginx must be modified.

          1. Create a new file docker-compose.override.yml in the mailcow-dockerized root folder and insert the following configuration -

          version: '2.1'
          +version: '2.1'
           services:
               portainer-mailcow:
                 image: portainer/portainer-ce
          @@ -2389,42 +2389,40 @@ services:
                 networks:
                   mailcow-network:
                     aliases:
          -            - portainer
          -
          + - portainer 2a. Create data/conf/nginx/portainer.conf: -
          upstream portainer {
          +```
          +upstream portainer {
             server portainer-mailcow:9000;
          -}
          -
          -map $http_upgrade $connection_upgrade {
          +}

          +

          map $http_upgrade $connection_upgrade { default upgrade; - '' close; + '' close; } -

          +```

          2b. Insert a new location to the default mailcow site by creating the file data/conf/nginx/site.portainer.custom: -

            location /portainer/ {
          +```
          +  location /portainer/ {
               proxy_http_version 1.1;
          -    proxy_set_header Host              $http_host;   # required for docker client's sake
          -    proxy_set_header X-Real-IP         $remote_addr; # pass on real client's IP
          +    proxy_set_header Host              $http_host;   # required for docker client's sake
          +    proxy_set_header X-Real-IP         $remote_addr; # pass on real client's IP
               proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
               proxy_set_header X-Forwarded-Proto $scheme;
          -    proxy_read_timeout                 900;
          -
          -    proxy_set_header Connection "";
          -    proxy_buffers 32 4k;
          -    proxy_pass http://portainer/;
          -  }
          -
          -  location /portainer/api/websocket/ {
          +    proxy_read_timeout                 900;

          +
          proxy_set_header Connection "";
          +proxy_buffers 32 4k;
          +proxy_pass http://portainer/;
          +
          +

          }

          +

          location /portainer/api/websocket/ { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; - proxy_pass http://portainer/api/websocket/; + proxy_pass http://portainer/api/websocket/; } -

          +```

          3. Apply your changes: -

          docker-compose up -d && docker-compose restart nginx-mailcow
          -

          +docker-compose up -d && docker-compose restart nginx-mailcow

          Now you can simply navigate to https://${MAILCOW_HOSTNAME}/portainer/ to view your Portainer container monitoring page. You’ll then be prompted to specify a new password for the admin account. After specifying your password, you’ll then be able to connect to the Portainer UI.


          @@ -2545,7 +2543,7 @@ map $http_upgrade $connection_upgrade { - + diff --git a/en/third_party/third_party-roundcube/index.html b/en/third_party/third_party-roundcube/index.html index ff78ba91e..1eebee93a 100644 --- a/en/third_party/third_party-roundcube/index.html +++ b/en/third_party/third_party-roundcube/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2357,38 +2357,134 @@
        4. + + Check for a newer release! + + +
        5. + +
        6. + + Change folder name + + +
        7. + +
        8. + + Change permissions + + +
        9. + +
        10. + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 + + +
        11. + +
        12. + + !/bin/bash + + + +
        13. + + Enter a bash session of the mailcow PHP container + + +
        14. + +
        15. + + Install required upgrade dependency, then upgrade Roundcube to wanted release + + +
        16. + +
        17. + + Type 'Y' and press enter to upgrade your install of Roundcube + + +
        18. + +
        19. + + Remove leftover files + + +
        20. + +
        21. + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 + + + + +
        22. + +
        23. + + Allow admins to log into Roundcube as email user (without any password) + + +
        24. + +
        25. + + Roundcube with plugin dovecot_impersonate must be installed first + +
      @@ -2438,38 +2534,134 @@
    • + + Check for a newer release! + + +
    • + +
    • + + Change folder name + + +
    • + +
    • + + Change permissions + + +
    • + +
    • + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 + + +
    • + +
    • + + !/bin/bash + + + +
    • + + Enter a bash session of the mailcow PHP container + + +
    • + +
    • + + Install required upgrade dependency, then upgrade Roundcube to wanted release + + +
    • + +
    • + + Type 'Y' and press enter to upgrade your install of Roundcube + + +
    • + +
    • + + Remove leftover files + + +
    • + +
    • + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 + + + + +
    • + +
    • + + Allow admins to log into Roundcube as email user (without any password) + + +
    • + +
    • + + Roundcube with plugin dovecot_impersonate must be installed first + +
    • @@ -2490,124 +2682,114 @@ -

      Roundcube

      -

      Installing Roundcube

      Download Roundcube 1.5.x to the web htdocs directory and extract it (here rc/): -

      # Check for a newer release!
      -cd data/web
      -wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz -
      -
      -# Change folder name
      -mv roundcubemail-1.5.2 rc
      -
      -# Change permissions
      -chown -R root: rc/
      -
      -# Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6
      -sed -i "s/\$prefix = '\.\/';/\$prefix = preg_replace\('\/\[\?\&]\.\*\$\/', '', \$_SERVER\['REQUEST_URI'] \?\? ''\) \?: '\.\/';/g" rc/program/include/rcmail.php
      -

      +```

      +

      Check for a newer release!

      +

      cd data/web +wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz -

      +

      Change folder name

      +

      mv roundcubemail-1.5.2 rc

      +

      Change permissions

      +

      chown -R root: rc/

      +

      Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6

      +

      sed -i "s/\$prefix = '.\/';/\$prefix = preg_replace('\/[\?\&].*\$\/', '', \$_SERVER['REQUEST_URI'] \?\? '') \?: '.\/';/g" rc/program/include/rcmail.php +```

      If you need spell check features, create a file data/hooks/phpfpm/aspell.sh with the following content, then chmod +x data/hooks/phpfpm/aspell.sh. This installs a local spell check engine. Note, most modern web browsers have built in spell check, so you may not want/need this. -

      #!/bin/bash
      -apk update
      +```

      +

      !/bin/bash

      +

      apk update apk add aspell-en # or any other language -

      +```

      Create a file data/web/rc/config/config.inc.php with the following content. - Change the des_key parameter to a random value. It is used to temporarily store your IMAP password. - The db_prefix is optional but recommended. - If you didn't install spell check in the above step, remove spellcheck_engine parameter and replace it with $config['enable_spellcheck'] = false;. -

      <?php
      +<?php
       error_reporting(0);
      -if (!file_exists('/tmp/mime.types')) {
      -file_put_contents("/tmp/mime.types", fopen("http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types", 'r'));
      +if (!file_exists('/tmp/mime.types')) {
      +file_put_contents("/tmp/mime.types", fopen("http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types", 'r'));
       }
       $config = array();
      -$config['db_dsnw'] = 'mysql://' . getenv('DBUSER') . ':' . getenv('DBPASS') . '@mysql/' . getenv('DBNAME');
      -$config['default_host'] = 'tls://dovecot';
      -$config['default_port'] = '143';
      -$config['smtp_server'] = 'tls://postfix';
      -$config['smtp_port'] = 587;
      -$config['smtp_user'] = '%u';
      -$config['smtp_pass'] = '%p';
      -$config['support_url'] = '';
      -$config['product_name'] = 'Roundcube Webmail';
      -$config['des_key'] = 'yourrandomstring_changeme';
      -$config['log_dir'] = '/dev/null';
      -$config['temp_dir'] = '/tmp';
      -$config['plugins'] = array(
      -  'archive',
      -  'managesieve'
      +$config['db_dsnw'] = 'mysql://' . getenv('DBUSER') . ':' . getenv('DBPASS') . '@mysql/' . getenv('DBNAME');
      +$config['default_host'] = 'tls://dovecot';
      +$config['default_port'] = '143';
      +$config['smtp_server'] = 'tls://postfix';
      +$config['smtp_port'] = 587;
      +$config['smtp_user'] = '%u';
      +$config['smtp_pass'] = '%p';
      +$config['support_url'] = '';
      +$config['product_name'] = 'Roundcube Webmail';
      +$config['des_key'] = 'yourrandomstring_changeme';
      +$config['log_dir'] = '/dev/null';
      +$config['temp_dir'] = '/tmp';
      +$config['plugins'] = array(
      +  'archive',
      +  'managesieve'
       );
      -$config['spellcheck_engine'] = 'aspell';
      -$config['mime_types'] = '/tmp/mime.types';
      -$config['imap_conn_options'] = array(
      -  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
      +$config['spellcheck_engine'] = 'aspell';
      +$config['mime_types'] = '/tmp/mime.types';
      +$config['imap_conn_options'] = array(
      +  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
       );
      -$config['enable_installer'] = true;
      -$config['smtp_conn_options'] = array(
      -  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
      +$config['enable_installer'] = true;
      +$config['smtp_conn_options'] = array(
      +  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
       );
      -$config['db_prefix'] = 'mailcow_rc1';
      -

      +$config['db_prefix'] = 'mailcow_rc1';

      Point your browser to https://myserver/rc/installer and follow the instructions. Initialize the database and leave the installer.

      Delete the directory data/web/rc/installer after a successful installation!

      Configure ManageSieve filtering

      Open data/web/rc/plugins/managesieve/config.inc.php and change the following parameters (or add them at the bottom of that file): -

      $config['managesieve_port'] = 4190;
      -$config['managesieve_host'] = 'tls://dovecot';
      -$config['managesieve_conn_options'] = array(
      -  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
      +$config['managesieve_port'] = 4190;
      +$config['managesieve_host'] = 'tls://dovecot';
      +$config['managesieve_conn_options'] = array(
      +  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
       );
       // Enables separate management interface for vacation responses (out-of-office)
       // 0 - no separate section (default),
       // 1 - add Vacation section,
       // 2 - add Vacation section, but hide Filters section
      -$config['managesieve_vacation'] = 1;
      -

      +$config['managesieve_vacation'] = 1;

      Enable change password function in Roundcube

      Open data/web/rc/config/config.inc.php and enable the password plugin:

      -
      ...
      -$config['plugins'] = array(
      -    'archive',
      -    'password',
      +

      ... +$config['plugins'] = array( + 'archive', + 'password', ); -... -

      +...

      Open data/web/rc/plugins/password/password.php, search for case 'ssha': and add above:

      -
              case 'ssha256':
      +

      case 'ssha256': $salt = rcube_utils::random_bytes(8); - $crypted = base64_encode( hash('sha256', $password . $salt, TRUE ) . $salt ); - $prefix = '{SSHA256}'; - break; -

      + $crypted = base64_encode( hash('sha256', $password . $salt, TRUE ) . $salt ); + $prefix = '{SSHA256}'; + break;

      Open data/web/rc/plugins/password/config.inc.php and change the following parameters (or add them at the bottom of that file):

      -
      $config['password_driver'] = 'sql';
      -$config['password_algorithm'] = 'ssha256';
      -$config['password_algorithm_prefix'] = '{SSHA256}';
      -$config['password_query'] = "UPDATE mailbox SET password = %P WHERE username = %u";
      -
      +

      $config['password_driver'] = 'sql'; +$config['password_algorithm'] = 'ssha256'; +$config['password_algorithm_prefix'] = '{SSHA256}'; +$config['password_query'] = "UPDATE mailbox SET password = %P WHERE username = %u";

      Integrate CardDAV addressbooks in Roundcube

      Download the latest release of RCMCardDAV to the Roundcube plugin directory and extract it (here rc/plugins): -

      cd data/web/rc/plugins
      +cd data/web/rc/plugins
       wget -O - https://github.com/mstilkerich/rcmcarddav/releases/download/v4.3.0/carddav-v4.3.0.tar.gz  | tar xfvz -
      -chown -R root: carddav/
      -

      +chown -R root: carddav/

      Copy the file config.inc.php.dist to config.inc.php (here in rc/plugins/carddav) and append the following preset to the end of the file - don't forget to replace mx.example.org with your own hostname: -

      $prefs['SOGo'] = array(
      -    'name'         =>  'SOGo',
      -    'username'     =>  '%u',
      -    'password'     =>  '%p',
      -    'url'          =>  'https://mx.example.org/SOGo/dav/%u/',
      -    'carddav_name_only' => true,
      -    'use_categories' => true,
      -    'active'       =>  true,
      -    'readonly'     =>  false,
      -    'refresh_time' => '02:00:00',
      -    'fixed'        =>  array( 'active', 'name', 'username', 'password', 'refresh_time' ),
      -    'hide'        =>  false,
      -);
      -
      +$prefs['SOGo'] = array( + 'name' => 'SOGo', + 'username' => '%u', + 'password' => '%p', + 'url' => 'https://mx.example.org/SOGo/dav/%u/', + 'carddav_name_only' => true, + 'use_categories' => true, + 'active' => true, + 'readonly' => false, + 'refresh_time' => '02:00:00', + 'fixed' => array( 'active', 'name', 'username', 'password', 'refresh_time' ), + 'hide' => false, +); Please note, that this preset only integrates the default addressbook (the one that's named "Personal Address Book" and can't be deleted). Additional addressbooks are currently not automatically detected but can be manually added within the roundecube settings.

      Enable the plugin by adding carddav to $config['plugins'] in rc/config/config.inc.php.

      If you want to remove the default addressbooks (stored in the Roundcube database), so that only the CardDAV addressbooks are accessible, append $config['address_book_type'] = ''; to the config file data/web/rc/config/config.inc.php.

      @@ -2615,75 +2797,70 @@ Please note, that this preset only integrates the default addressbook (the one t

      Optionally, you can add Roundcube's link to the mailcow Apps list. To do this, open or create data/web/inc/vars.local.inc.php and add the following code-block:

      NOTE: Don't forget to add the <?php delimiter on the first line

      -
      ...
      +

      ... $MAILCOW_APPS = array( array( - 'name' => 'SOGo', - 'link' => '/SOGo/' + 'name' => 'SOGo', + 'link' => '/SOGo/' ), array( - 'name' => 'Roundcube', - 'link' => '/rc/' + 'name' => 'Roundcube', + 'link' => '/rc/' ) ); -... -

      +...

      Upgrading Roundcube

      Upgrading Roundcube is rather simple, go to the Github releases page for Roundcube and get the link for the "complete.tar.gz" file for the wanted release. Then follow the below commands and change the URL and Roundcube folder name if needed.

      -
      # Enter a bash session of the mailcow PHP container
      -docker exec -it mailcowdockerized_php-fpm-mailcow_1 bash
      -
      -# Install required upgrade dependency, then upgrade Roundcube to wanted release
      -apk add rsync
      +

      ```

      +

      Enter a bash session of the mailcow PHP container

      +

      docker exec -it mailcowdockerized_php-fpm-mailcow_1 bash

      +

      Install required upgrade dependency, then upgrade Roundcube to wanted release

      +

      apk add rsync cd /tmp -wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz - +wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz - cd roundcubemail-1.5.2 -bin/installto.sh /web/rc - -# Type 'Y' and press enter to upgrade your install of Roundcube - -# Remove leftover files -cd /tmp -rm -rf roundcube* - -# Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 -sed -i "s/\$prefix = '\.\/';/\$prefix = preg_replace\('\/\[\?\&]\.\*\$\/', '', \$_SERVER\['REQUEST_URI'] \?\? ''\) \?: '\.\/';/g" /web/rc/program/include/rcmail.php -

      +bin/installto.sh /web/rc

      +

      Type 'Y' and press enter to upgrade your install of Roundcube

      +

      Remove leftover files

      +

      cd /tmp +rm -rf roundcube*

      +

      Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6

      +

      sed -i "s/\$prefix = '.\/';/\$prefix = preg_replace('\/[\?\&].*\$\/', '', \$_SERVER['REQUEST_URI'] \?\? '') \?: '.\/';/g" /web/rc/program/include/rcmail.php +```

      Let admins log into Roundcube without password

      First, install plugin dovecot_impersonate and add Roundcube as an app (see above).

      Edit mailcow.conf and add the following:

      -
      # Allow admins to log into Roundcube as email user (without any password)
      -# Roundcube with plugin dovecot_impersonate must be installed first
      -
      -ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=y
      -
      +

      ```

      +

      Allow admins to log into Roundcube as email user (without any password)

      +

      Roundcube with plugin dovecot_impersonate must be installed first

      +

      ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=y +```

      Edit docker-compose.override.yml and crate/extend the section for php-fpm-mailcow:

      -
      version: '2.1'
      +

      yml +version: '2.1' services: php-fpm-mailcow: environment: - - ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=${ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE:-n} -

      + - ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=${ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE:-n}

      Edit data/web/js/site/mailbox.js and the following code after if (ALLOW_ADMIN_EMAIL_LOGIN) { ... }

      -
      if (ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE) {
      -  item.action += '<a href="/rc-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs ' + btnSize + ' btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> Roundcube</a>';
      -}
      -
      +

      js +if (ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE) { + item.action += '<a href="/rc-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs ' + btnSize + ' btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> Roundcube</a>'; +}

      Edit data/web/mailbox.php and add this line to array $template_data:

      -
        'allow_admin_email_login_roundcube' => (preg_match("/^(yes|y)+$/i", $_ENV["ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE"])) ? 'true' : 'false',
      -
      +

      php + 'allow_admin_email_login_roundcube' => (preg_match("/^(yes|y)+$/i", $_ENV["ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE"])) ? 'true' : 'false',

      Edit data/web/templates/mailbox.twig and add this code to the bottom of the javascript section:

      -
        var ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE = {{ allow_admin_email_login_roundcube }};
      -
      +

      js + var ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE = {{ allow_admin_email_login_roundcube }};

      Copy the contents of the following files from this Snippet:

      • data/web/inc/lib/RoundcubeAutoLogin.php
      • data/web/rc-auth.php

      Finally, restart mailcow

      -
      docker-compose down
      -docker-compose up -d
      -
      +

      docker-compose down +docker-compose up -d


      @@ -2788,7 +2965,7 @@ docker-compose up -d - + diff --git a/en/troubleshooting/debug-admin_login_sogo/index.html b/en/troubleshooting/debug-admin_login_sogo/index.html index be9e974a2..1003dbce7 100644 --- a/en/troubleshooting/debug-admin_login_sogo/index.html +++ b/en/troubleshooting/debug-admin_login_sogo/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2456,11 +2456,9 @@ log into SOGo as a mailbox user, without knowing the users password.

      Multiple concurrent admin-logins to different mailboxes are also possible when using this feature.

      Enabling the feature

      The feature is disabled by default. It can be enabled in the mailcow.conf by setting: -

      ALLOW_ADMIN_EMAIL_LOGIN=y
      -
      +ALLOW_ADMIN_EMAIL_LOGIN=y and recreating the affected containers with -
      docker-compose up -d
      -

      +docker-compose up -d

      Drawbacks when enabled

      • Each SOGo page-load and each Active-Sync request will cause an additional execution of an internal PHP script. @@ -2606,7 +2604,7 @@ In most cases, this should not be noticeable but should be kept in mind if you f - + diff --git a/en/troubleshooting/debug-attach_service/index.html b/en/troubleshooting/debug-attach_service/index.html index 864302185..7411ca143 100644 --- a/en/troubleshooting/debug-attach_service/index.html +++ b/en/troubleshooting/debug-attach_service/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2504,17 +2504,14 @@

        Attaching a Container to your Shell

        To attach a container to your shell you can simply run

        -
        docker-compose exec $Service_Name /bin/bash
        -
        +

        docker-compose exec $Service_Name /bin/bash

        Connecting to Services

        If you want to connect to a service / application directly it is always a good idea to source mailcow.conf to get all relevant variables into your environment.

        MySQL

        -
        source mailcow.conf
        -docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
        -
        +

        source mailcow.conf +docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}

        Redis

        -
        docker-compose exec redis-mailcow redis-cli
        -
        +

        docker-compose exec redis-mailcow redis-cli

        Service Descriptions

        Here is a brief overview of what container / service does what:

      @@ -2710,7 +2707,7 @@ docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} - + diff --git a/en/troubleshooting/debug-common_problems/index.html b/en/troubleshooting/debug-common_problems/index.html index b8177992f..1e67efc28 100644 --- a/en/troubleshooting/debug-common_problems/index.html +++ b/en/troubleshooting/debug-common_problems/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -801,52 +801,65 @@
    • + + telnet 74.125.133.27 465 + + + +
    • @@ -2466,52 +2479,65 @@
    • + + telnet 74.125.133.27 465 + + + +
    • @@ -2532,8 +2558,6 @@ -

      Common Problems

      -

      Here we list common problems and possible solutions:

      Mail loops back to myself

      Please check in your mailcow UI if you made the domain a backup MX:

      @@ -2544,11 +2568,12 @@
    • Check if your IP address is on any blacklists. You could use dnsbl.info or any other similar service to check for your IP address.
    • There are some consumer ISP routers out there, that block mail ports for non whitelisted domains. Please check if you can reach your server on the ports 465 or 587:
    • -
      # telnet 74.125.133.27 465
      -Trying 74.125.133.27...
      +

      ```

      +

      telnet 74.125.133.27 465

      +

      Trying 74.125.133.27... Connected to 74.125.133.27. -Escape character is '^]'. -

      +Escape character is '^]'. +```

      My mails are identified as Spam

      Please read our guide on DNS configuration.

      docker-compose throws weird errors

      @@ -2565,8 +2590,7 @@ Escape character is '^]'.

      It might also be wrongly linked file (i.e. SSL certificate) that prevents a crucial container (nginx) from starting, so always check your logs to get an idea where your problem is coming from.

      Address already in use

      If you get an error message like:

      -
      ERROR: for postfix-mailcow  Cannot start service postfix-mailcow: driver failed programming external     connectivity on endpoint mailcowdockerized_postfix-mailcow_1: Error starting userland proxy: listen tcp 0.0.0.0:25: bind: address already in use
      -
      +

      ERROR: for postfix-mailcow Cannot start service postfix-mailcow: driver failed programming external connectivity on endpoint mailcowdockerized_postfix-mailcow_1: Error starting userland proxy: listen tcp 0.0.0.0:25: bind: address already in use

      while trying to start / install mailcow: dockerized, make sure you've followed our section on the prerequisites.

      XYZ can't connect to ...

      Please check your local firewall! @@ -2574,19 +2598,17 @@ Docker and iptables-based firewalls sometimes create conflicting rules, so disab

      If you experience connection problems from home, please check your ISP router's firewall too, some of them block mail traffic on the SMTP (587) or SMTPS (465) ports. It could also be, that your ISP is blocking the ports for SUBMISSION (25).

      While Linux users can chose from a variety of tools1 to check if a port is open, the Windows user has only the PowerShell command Test-NetConnection -ComputerName host -Port port available by default.

      To enable telnet on a Windows after Vista please check this guide or enter the following command in an terminal with administrator privileges:

      -
      dism /online /Enable-Feature /FeatureName:TelnetClient
      -
      +

      dism /online /Enable-Feature /FeatureName:TelnetClient

      Inotify instance limit for user 5000 (UID vmail) exceeded (see #453)

      Docker containers use the Docker hosts inotify limits. Setting them on your Docker host will pass them to the container.

      Dovecot keeps restarting (see #2672)

      Check that you have at least the following files in data/assets/ssl:

      -
      cert.pem
      +

      cert.pem dhparams.pem -key.pem -

      +key.pem

      If dhparams.pem is missing, you can generate it with

      -
      openssl dhparam -out data/assets/ssl/dhparams.pem 4096
      -
      +

      bash +openssl dhparam -out data/assets/ssl/dhparams.pem 4096


        @@ -2714,7 +2736,7 @@ key.pem - + diff --git a/en/troubleshooting/debug-logs/index.html b/en/troubleshooting/debug-logs/index.html index 181d11df5..dcffcecb6 100644 --- a/en/troubleshooting/debug-logs/index.html +++ b/en/troubleshooting/debug-logs/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2508,7 +2508,7 @@ - + diff --git a/en/troubleshooting/debug-mysql_aria/index.html b/en/troubleshooting/debug-mysql_aria/index.html index 7c465a9e6..bedfee0a4 100644 --- a/en/troubleshooting/debug-mysql_aria/index.html +++ b/en/troubleshooting/debug-mysql_aria/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -833,6 +833,41 @@ MariaDB: Aria recovery after crash + + +
      1. + + Stop the stack, don't run "down" + + +
      2. + +
      3. + + Run a bash in the stopped container as user mysql + + +
      4. + +
      5. + + cd to the SQL data directory + + +
      6. + +
      7. + + Run aria_chk + + +
      8. + +
      9. + + Delete aria log files + +
      10. @@ -2400,6 +2435,41 @@ MariaDB: Aria recovery after crash + + +
      11. + + Stop the stack, don't run "down" + + +
      12. + +
      13. + + Run a bash in the stopped container as user mysql + + +
      14. + +
      15. + + cd to the SQL data directory + + +
      16. + +
      17. + + Run aria_chk + + +
      18. + +
      19. + + Delete aria log files + +
      20. @@ -2420,23 +2490,22 @@ -

        Recover crashed Aria storage engine

        -

        MariaDB: Aria recovery after crash

        If your server crashed and MariaDB logs an error similar to [ERROR] mysqld: Aria recovery failed. Please run aria_chk -r on all Aria tables (*.MAI) and delete all aria_log.######## files you may want to try the following to recover the database to a healthy state:

        Start the stack and wait until mysql-mailcow begins to report a restarting state. Check by running docker-compose ps.

        Now run the following commands:

        -
        # Stop the stack, don't run "down"
        -docker-compose stop
        -# Run a bash in the stopped container as user mysql
        -docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql bash"' mysql-mailcow
        -# cd to the SQL data directory
        -cd /var/lib/mysql
        -# Run aria_chk
        -aria_chk --check --force */*.MAI
        -# Delete aria log files
        -rm aria_log.*
        -
        +

        ```

        +

        Stop the stack, don't run "down"

        +

        docker-compose stop

        +

        Run a bash in the stopped container as user mysql

        +

        docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql bash"' mysql-mailcow

        +

        cd to the SQL data directory

        +

        cd /var/lib/mysql

        +

        Run aria_chk

        +

        aria_chk --check --force /.MAI

        +

        Delete aria log files

        +

        rm aria_log.* +```

        Now run docker-compose down followed by docker-compose up -d.


        @@ -2557,7 +2626,7 @@ rm aria_log.* - + diff --git a/en/troubleshooting/debug-mysql_upgrade/index.html b/en/troubleshooting/debug-mysql_upgrade/index.html index cc88a4563..b29c3754e 100644 --- a/en/troubleshooting/debug-mysql_upgrade/index.html +++ b/en/troubleshooting/debug-mysql_upgrade/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2424,13 +2424,11 @@

        Run a manual mysql_upgrade

        This step is usually not necessary.

        -
        docker-compose stop mysql-mailcow watchdog-mailcow
        -docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && bash && exit 0"' mysql-mailcow
        -
        +

        docker-compose stop mysql-mailcow watchdog-mailcow +docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && bash && exit 0"' mysql-mailcow

        As soon as the SQL shell spawned, run mysql_upgrade and exit the container:

        -
        mysql_upgrade
        -exit
        -
        +

        mysql_upgrade +exit


        @@ -2550,7 +2548,7 @@ exit - + diff --git a/en/troubleshooting/debug-reset_pw/index.html b/en/troubleshooting/debug-reset_pw/index.html index d752c5238..7d09b091d 100644 --- a/en/troubleshooting/debug-reset_pw/index.html +++ b/en/troubleshooting/debug-reset_pw/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -878,6 +878,26 @@ + + + + + +
      21. + + source mailcow.conf + + +
      22. + +
      23. + + docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} + + + - -
      24. - -
      25. +
      26. Remove Two-Factor Authentication @@ -935,6 +950,11 @@ +
      27. + + + + @@ -2491,6 +2511,26 @@ + + + + + +
      28. + + source mailcow.conf + + +
      29. + +
      30. + + docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} + + + - -
      31. - -
      32. +
      33. Remove Two-Factor Authentication @@ -2548,6 +2583,11 @@ +
      34. + + + + @@ -2568,22 +2608,19 @@ -

        Reset Passwords (incl. SQL)

        -

        mailcow Admin Account

        Resets the mailcow admin account to a random password. Older mailcow: dockerized installations may find the mailcow-reset-admin.sh script in their mailcow root directory (mailcow_path).

        -
        cd mailcow_path
        -./helper-scripts/mailcow-reset-admin.sh
        -
        +

        cd mailcow_path +./helper-scripts/mailcow-reset-admin.sh

        Reset MySQL Passwords

        Stop the stack by running docker-compose stop.

        When the containers came to a stop, run this command:

        -
        docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && mysql -hlocalhost -uroot && exit 0"' mysql-mailcow
        -
        +

        docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && mysql -hlocalhost -uroot && exit 0"' mysql-mailcow

        1. Find database name

        -
        # source mailcow.conf
        -# docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
        -MariaDB [(none)]> show databases;
        +

        ```

        +

        source mailcow.conf

        +

        docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}

        +

        MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ @@ -2593,49 +2630,47 @@ MariaDB [(none)]> show databases; | performance_schema | +--------------------+ 4 rows in set (0.00 sec) -

        +```

        2. Reset one or more users

        2.1 Maria DB < 10.4 (older mailcow installations)

        Both "password" and "authentication_string" exist. Currently "password" is used, but better set both.

        -
        MariaDB [(none)]> SELECT user FROM mysql.user;
        +

        ``` +MariaDB [(none)]> SELECT user FROM mysql.user; +--------------+ | user | +--------------+ | mailcow | <===== | root | +--------------+ -2 rows in set (0.00 sec) - +2 rows in set (0.00 sec)

        +

        MariaDB [(none)]> FLUSH PRIVILEGES; +MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('gotr00t'), password = PASSWORD('gotr00t') WHERE User = 'root'; +MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('mookuh'), password = PASSWORD('mookuh') WHERE User = 'mailcow' AND Host = '%'; MariaDB [(none)]> FLUSH PRIVILEGES; -MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('gotr00t'), password = PASSWORD('gotr00t') WHERE User = 'root'; -MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('mookuh'), password = PASSWORD('mookuh') WHERE User = 'mailcow' AND Host = '%'; -MariaDB [(none)]> FLUSH PRIVILEGES; -

        +```

        2.2 Maria DB >= 10.4 (current mailcows)

        -
        MariaDB [(none)]> SELECT user FROM mysql.user;
        +

        ``` +MariaDB [(none)]> SELECT user FROM mysql.user; +--------------+ | user | +--------------+ | mailcow | <===== | root | +--------------+ -2 rows in set (0.00 sec) - +2 rows in set (0.00 sec)

        +

        MariaDB [(none)]> FLUSH PRIVILEGES; +MariaDB [(none)]> ALTER USER 'mailcow'@'%' IDENTIFIED BY 'mookuh'; +MariaDB [(none)]> ALTER USER 'root'@'%' IDENTIFIED BY 'gotr00t'; +MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'gotr00t'; MariaDB [(none)]> FLUSH PRIVILEGES; -MariaDB [(none)]> ALTER USER 'mailcow'@'%' IDENTIFIED BY 'mookuh'; -MariaDB [(none)]> ALTER USER 'root'@'%' IDENTIFIED BY 'gotr00t'; -MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'gotr00t'; -MariaDB [(none)]> FLUSH PRIVILEGES; -

        +```

        Remove Two-Factor Authentication

        For mailcow WebUI:

        This works similar to resetting a MySQL password, now we do it from the host without connecting to the MySQL CLI:

        -
        source mailcow.conf
        -docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='YOUR_USERNAME';"
        -
        +

        source mailcow.conf +docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='YOUR_USERNAME';"

        For SOGo:

        -
        docker-compose exec -u sogo sogo-mailcow sogo-tool user-preferences set defaults user@example.com SOGoGoogleAuthenticatorEnabled '{"SOGoGoogleAuthenticatorEnabled":0}'
        -
        +

        docker-compose exec -u sogo sogo-mailcow sogo-tool user-preferences set defaults user@example.com SOGoGoogleAuthenticatorEnabled '{"SOGoGoogleAuthenticatorEnabled":0}'


        @@ -2755,7 +2790,7 @@ docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e &qu - + diff --git a/en/troubleshooting/debug-reset_tls/index.html b/en/troubleshooting/debug-reset_tls/index.html index 23e919bc0..9b2c1cc97 100644 --- a/en/troubleshooting/debug-reset_tls/index.html +++ b/en/troubleshooting/debug-reset_tls/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2374,14 +2374,13 @@

        Reset TLS certificates

        In case you encounter problems with your certificate, key or Let's Encrypt account, please try to reset the TLS assets:

        -
        source mailcow.conf
        +

        source mailcow.conf docker-compose down rm -rf data/assets/ssl mkdir data/assets/ssl -openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes +openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes cp -n -d data/assets/ssl-example/*.pem data/assets/ssl/ -docker-compose up -d -

        +docker-compose up -d

        This will stop mailcow, source the variables we need, create a self-signed certificate and start mailcow.

        If you use Let's Encrypt you should be careful as you will create a new account and a new set of certificates. You will run into a ratelimit sooner or later.

        Please also note that previous TLSA records will be invalid.

        @@ -2504,7 +2503,7 @@ docker-compose up -d - + diff --git a/en/troubleshooting/debug-rm_volumes/index.html b/en/troubleshooting/debug-rm_volumes/index.html index 416fbf252..04c14a415 100644 --- a/en/troubleshooting/debug-rm_volumes/index.html +++ b/en/troubleshooting/debug-rm_volumes/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,8 +2376,7 @@

        You may want to remove a set of persistent data to resolve a conflict or to start over.

        mailcowdockerized can vary and depends on your compose project name (if it's unchanged, mailcowdockerized is the correct value). If you are unsure about volume names, run docker volume ls for a full list.

        Delete a single volume:

        -
        docker volume rm mailcowdockerized_${VOLUME_NAME}
        -
        +

        docker volume rm mailcowdockerized_${VOLUME_NAME}

        • Remove volume mysql-vol-1 to remove all MySQL data.
        • Remove volume redis-vol-1 to remove all Redis data.
        • @@ -2505,7 +2504,7 @@ - + diff --git a/en/troubleshooting/debug-rspamd_memory_leaks/index.html b/en/troubleshooting/debug-rspamd_memory_leaks/index.html index bdf66964f..e1cdcd58e 100644 --- a/en/troubleshooting/debug-rspamd_memory_leaks/index.html +++ b/en/troubleshooting/debug-rspamd_memory_leaks/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,24 +2380,18 @@ -

          Advanced: Find memory leaks in Rspamd

          -

          A quick guide to deeply analyze a malfunctioning Rspamd.

          -
          docker-compose exec rspamd-mailcow bash
          -
          -if ! grep -qi 'apt-stable-asan' /etc/apt/sources.list.d/rspamd.list; then
          -  sed -i 's/apt-stable/apt-stable-asan/i' /etc/apt/sources.list.d/rspamd.list
          -fi
          -
          -apt-get update ; apt-get upgrade rspamd
          -
          -nano /docker-entrypoint.sh
          -
          -# Before "exec "$@"" add the following lines:
          -
          -export G_SLICE=always-malloc
          -export ASAN_OPTIONS=new_delete_type_mismatch=0:detect_leaks=1:detect_odr_violation=0:log_path=/tmp/rspamd-asan:quarantine_size_mb=2048:malloc_context_size=8:fast_unwind_on_malloc=0
          -
          +

          ``` +docker-compose exec rspamd-mailcow bash

          +

          if ! grep -qi 'apt-stable-asan' /etc/apt/sources.list.d/rspamd.list; then + sed -i 's/apt-stable/apt-stable-asan/i' /etc/apt/sources.list.d/rspamd.list +fi

          +

          apt-get update ; apt-get upgrade rspamd

          +

          nano /docker-entrypoint.sh

          +

          Before "exec "$@"" add the following lines:

          +

          export G_SLICE=always-malloc +export ASAN_OPTIONS=new_delete_type_mismatch=0:detect_leaks=1:detect_odr_violation=0:log_path=/tmp/rspamd-asan:quarantine_size_mb=2048:malloc_context_size=8:fast_unwind_on_malloc=0

          +

          ```

          Restart Rspamd: docker-compose restart rspamd-mailcow

          Your memory consumption will increase by a lot, it will also steadily grow, which is not related to a possible memory leak you are looking for.

          Leave the container running for a few minutes, hours or days (it should match the time you usually wait for the leak to "happen") and restart it: docker-compose restart rspamd-mailcow.

          @@ -2512,7 +2515,7 @@ export ASAN_OPTIONS=new_delete_type_mismatch=0:detect_leaks=1:detect_odr_violati - + diff --git a/en/troubleshooting/debug/index.html b/en/troubleshooting/debug/index.html index dfec93008..1152424d4 100644 --- a/en/troubleshooting/debug/index.html +++ b/en/troubleshooting/debug/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2502,7 +2502,7 @@ - + diff --git a/i_u_m/i_u_m_deinstall/index.html b/i_u_m/i_u_m_deinstall/index.html index 5139a6192..aff1847c4 100644 --- a/i_u_m/i_u_m_deinstall/index.html +++ b/i_u_m/i_u_m_deinstall/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2374,8 +2374,7 @@

          Deinstallation

          To remove mailcow: dockerized with all it's volumes, images and containers do:

          -
          docker-compose down -v --rmi all --remove-orphans
          -
          +

          docker-compose down -v --rmi all --remove-orphans

          Info

            @@ -2504,7 +2503,7 @@ - + diff --git a/i_u_m/i_u_m_install/index.html b/i_u_m/i_u_m_install/index.html index ca02b2eb7..c621feb5f 100644 --- a/i_u_m/i_u_m_install/index.html +++ b/i_u_m/i_u_m_install/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,66 +2380,58 @@ -

            Installation

            -

            You need Docker (a version >= 20.10.2 is required) and Docker Compose (a version <= 2.0 is required).

            1. Learn how to install Docker and Docker Compose.

            Quick installation for most operation systems:

              -
            • -

              Docker -

              curl -sSL https://get.docker.com/ | CHANNEL=stable sh
              -# After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS 7)
              -systemctl enable --now docker
              -

              -
            • -
            • -

              Docker-Compose

              -
            • +
            • Docker +``` +curl -sSL https://get.docker.com/ | CHANNEL=stable sh
            • +
            +

            After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS 7)

            +

            systemctl enable --now docker +```

            +
              +
            • Docker-Compose

            Warning

            mailcow requires the latest version of docker-compose v1. It is highly recommended to use the commands below to install docker-compose. Package managers (e.g. apt, yum) likely won't give you the correct version. Note: This command downloads docker-compose from the official Docker Github repository and is a safe method. The snippet will determine the latest supported version by mailcow. In almost all cases this is the latest version available (exceptions are broken releases or major changes not yet supported by mailcow).

            -
            curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose
            -chmod +x /usr/local/bin/docker-compose
            -
            +

            curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose

            Please use the latest Docker engine available and do not use the engine that ships with your distros repository.

            1.1. On SELinux enabled systems, e.g. CentOS 7:

            • Check if "container-selinux" package is present on your system:
            -
            rpm -qa | grep container-selinux
            -
            +

            rpm -qa | grep container-selinux

            If the above command returns an empty or no output, you should install it via your package manager.

            • Check if docker has SELinux support enabled:
            -
            docker info | grep selinux
            -
            +

            docker info | grep selinux

            If the above command returns an empty or no output, create or edit /etc/docker/daemon.json and add "selinux-enabled": true. Example file content:

            -
            {
            -  "selinux-enabled": true
            -}
            -
            +

            { + "selinux-enabled": true +}

            Restart the docker daemon and verify SELinux is now enabled.

            This step is required to make sure mailcows volumes are properly labeled as declared in the compose file. If you are interested in how this works, you can check out the readme of https://github.com/containers/container-selinux which links to a lot of useful information on that topic.

            2. Clone the master branch of the repository, make sure your umask equals 0022. Please clone the repository as root user and also control the stack as root. We will modify attributes - if necessary - while bootstrapping the containers automatically and make sure everything is secured. The update.sh script must therefore also be run as root. It might be necessary to change ownership and other attributes of files you will otherwise not have access to. We drop permissions for every exposed application and will not run an exposed service as root! Controlling the Docker daemon as non-root user does not give you additional security. The unprivileged user will spawn the containers as root likewise. The behaviour of the stack is identical.

            -
            $ su
            -# umask
            -0022 # <- Verify it is 0022
            -# cd /opt
            -# git clone https://github.com/mailcow/mailcow-dockerized
            -# cd mailcow-dockerized
            -
            +

            ``` +$ su

            +

            umask

            +

            0022 # <- Verify it is 0022

            +

            cd /opt

            +

            git clone https://github.com/mailcow/mailcow-dockerized

            +

            cd mailcow-dockerized

            +

            ```

            3. Generate a configuration file. Use a FQDN (host.domain.tld) as hostname when asked. -

            ./generate_config.sh
            -

            +./generate_config.sh

            4. Change configuration if you want or need to. -

            nano mailcow.conf
            -
            +nano mailcow.conf If you plan to use a reverse proxy, you can, for example, bind HTTPS to 127.0.0.1 on port 8443 and HTTP to 127.0.0.1 on port 8080.

            You may need to stop an existing pre-installed MTA which blocks port 25/tcp. See this chapter to learn how to reconfigure Postfix to run besides mailcow after a successful installation.

            Some updates modify mailcow.conf and add new parameters. It is hard to keep track of them in the documentation. Please check their description and, if unsure, ask at the known channels for advise.

            @@ -2438,20 +2439,18 @@ If you plan to use a reverse proxy, you can, for example, bind HTTPS to 127.0.0.

            Whenever you run into trouble and strange phenomena, please check your MTU.

            Edit docker-compose.yml and change the network settings according to your MTU. Add the new driver_opts parameter like this: -

            networks:
            +networks:
               mailcow-network:
                 ...
                 driver_opts:
                   com.docker.network.driver.mtu: 1450
            -    ...
            -

            + ...

            4.2. Users without an IPv6 enabled network on their host system:

            Enable IPv6. Finally.

            If you do not have an IPv6 enabled network on your host and you don't care for a better internet (thehe), it is recommended to disable IPv6 for the mailcow network to prevent unforeseen issues.

            5. Pull the images and run the compose file. The parameter -d will start mailcow: dockerized detached: -

            docker-compose pull
            -docker-compose up -d
            -

            +docker-compose pull +docker-compose up -d

            Done!

            You can now access https://${MAILCOW_HOSTNAME} with the default credentials admin + password moohoo.

            @@ -2579,7 +2578,7 @@ docker-compose up -d - + diff --git a/i_u_m/i_u_m_migration/index.html b/i_u_m/i_u_m_migration/index.html index aa766738c..759e23bc6 100644 --- a/i_u_m/i_u_m_migration/index.html +++ b/i_u_m/i_u_m_migration/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,8 +2380,6 @@ -

            Migration

            -

            Warning

            This guide assumes you intend to migrate an existing mailcow server (source) over to a brand new, empty server (target). It takes no care about preserving any existing data on your target server and will erase anything within /var/lib/docker/volumes and thus any Docker volumes you may have already set up.

            @@ -2385,45 +2392,37 @@ Install
            Docker and Docker Compose on your new server.

            Quick installation for most operation systems:

              -
            • -

              Docker -

              curl -sSL https://get.docker.com/ | CHANNEL=stable sh
              -# After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS 7)
              -systemctl enable docker.service
              -

              -
            • -
            • -

              docker-compose -

              curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose
              -chmod +x /usr/local/bin/docker-compose
              -

              -
            • +
            • Docker +``` +curl -sSL https://get.docker.com/ | CHANNEL=stable sh
            • +
            +

            After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS 7)

            +

            systemctl enable docker.service +```

            +
              +
            • docker-compose +curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose

            Please use the latest Docker engine available and do not use the engine that ships with your distros repository.

            2. Stop Docker and assure Docker has stopped: -

            systemctl stop docker.service
            -systemctl status docker.service
            -

            +systemctl stop docker.service +systemctl status docker.service

            3. Run the following commands on the source machine (take care of adding the trailing slashes in the first path parameter as shown below!) - WARNING: This command will erase anything that may already exist under /var/lib/docker/volumes on the target machine: -

            rsync -aHhP --numeric-ids --delete /opt/mailcow-dockerized/ root@target-machine.example.com:/opt/mailcow-dockerized
            -rsync -aHhP --numeric-ids --delete /var/lib/docker/volumes/ root@target-machine.example.com:/var/lib/docker/volumes
            -

            +rsync -aHhP --numeric-ids --delete /opt/mailcow-dockerized/ root@target-machine.example.com:/opt/mailcow-dockerized +rsync -aHhP --numeric-ids --delete /var/lib/docker/volumes/ root@target-machine.example.com:/var/lib/docker/volumes

            4. Shut down mailcow and stop Docker on the source machine. -

            cd /opt/mailcow-dockerized
            +cd /opt/mailcow-dockerized
             docker-compose down
            -systemctl stop docker.service
            -

            +systemctl stop docker.service

            5. Repeat step 3 with the same commands. This will be much quicker than the first time.

            6. Switch over to the target machine and start Docker. -

            systemctl start docker.service
            -

            +systemctl start docker.service

            7. Now pull the mailcow Docker images on the target machine. -

            cd /opt/mailcow-dockerized
            -docker-compose pull
            -

            +cd /opt/mailcow-dockerized +docker-compose pull

            8. Start the whole mailcow stack and everything should be done! -

            docker-compose up -d
            -

            +docker-compose up -d

            9. Finally, change your DNS settings to point to the target server.


            @@ -2544,7 +2543,7 @@ docker-compose pull - + diff --git a/i_u_m/i_u_m_update/index.html b/i_u_m/i_u_m_update/index.html index 44d0cf923..6f7a58ee8 100644 --- a/i_u_m/i_u_m_update/index.html +++ b/i_u_m/i_u_m_update/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -419,6 +419,82 @@ +
          + + + + +
        • + + Options can be combined + + +
        • + +
        • + + - Check for updates and show changes + + +
        • + +
        • + + Do not try to update docker-compose, make sure to use the latest docker-compose available + + +
        • + +
        • + + - Do not start mailcow after applying an update + + +
        • + +
        • + + - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine) + + +
        • + +
        • + + - Force update (unattended, but unsupported, use at own risk) + + +
        • + +
        • + + - Run garbage collector to cleanup old image tags and exit + + +
        • + +
        • + + - Update with merge strategy option "ours" instead of "theirs" + + +
        • + +
        • + + This will solve conflicts when merging in favor for your local changes and should be avoided. Local changes will always be kept, unless we changed file XY, too. + + +
        • + +
        • + + - Don't update, but prefetch images and exit + + + + +
        • + +
        • + + Replace commit ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab by your ID + + + - -
        • - -
        • +
        • Update Cycle +
        • + +
        + + @@ -2451,6 +2540,82 @@ + + + + + +
      35. + + Options can be combined + + +
      36. + +
      37. + + - Check for updates and show changes + + +
      38. + +
      39. + + Do not try to update docker-compose, make sure to use the latest docker-compose available + + +
      40. + +
      41. + + - Do not start mailcow after applying an update + + +
      42. + +
      43. + + - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine) + + +
      44. + +
      45. + + - Force update (unattended, but unsupported, use at own risk) + + +
      46. + +
      47. + + - Run garbage collector to cleanup old image tags and exit + + +
      48. + +
      49. + + - Update with merge strategy option "ours" instead of "theirs" + + +
      50. + +
      51. + + This will solve conflicts when merging in favor for your local changes and should be avoided. Local changes will always be kept, unless we changed file XY, too. + + +
      52. + +
      53. + + - Don't update, but prefetch images and exit + + + + +
      54. + +
      55. + + Replace commit ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab by your ID + + + - -
      56. - -
      57. +
      58. Update Cycle +
      59. + + + + @@ -2502,60 +2680,50 @@ -

        Update

        -

        Automatic update

        An update script in your mailcow-dockerized directory will take care of updates.

        But use it with caution! If you think you made a lot of changes to the mailcow code, you should use the manual update guide below.

        Run the update script: -

        ./update.sh
        -

        +./update.sh

        If it needs to, it will ask you how you wish to proceed. Merge errors will be reported. Some minor conflicts will be auto-corrected (in favour for the mailcow: dockerized repository code).

        Options

        -
        # Options can be combined
        -
        -# - Check for updates and show changes
        -./update.sh --check
        -
        -# Do not try to update docker-compose, **make sure to use the latest docker-compose available**
        -./update.sh --no-update-compose
        -
        -# - Do not start mailcow after applying an update
        -./update.sh --skip-start
        -
        -# - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine)
        -./update.sh --skip-ping-check
        -
        -# - Force update (unattended, but unsupported, use at own risk)
        -./update.sh --force
        -
        -# - Run garbage collector to cleanup old image tags and exit
        -./update.sh --gc
        -
        -# - Update with merge strategy option "ours" instead of "theirs"
        -#   This will **solve conflicts** when merging in favor for your local changes and should be avoided. Local changes will always be kept, unless we changed file XY, too.
        -./update.sh --ours
        -
        -# - Don't update, but prefetch images and exit
        -./update.sh --prefetch
        -
        +

        ```

        +

        Options can be combined

        +

        - Check for updates and show changes

        +

        ./update.sh --check

        +

        Do not try to update docker-compose, make sure to use the latest docker-compose available

        +

        ./update.sh --no-update-compose

        +

        - Do not start mailcow after applying an update

        +

        ./update.sh --skip-start

        +

        - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine)

        +

        ./update.sh --skip-ping-check

        +

        - Force update (unattended, but unsupported, use at own risk)

        +

        ./update.sh --force

        +

        - Run garbage collector to cleanup old image tags and exit

        +

        ./update.sh --gc

        +

        - Update with merge strategy option "ours" instead of "theirs"

        +

        This will solve conflicts when merging in favor for your local changes and should be avoided. Local changes will always be kept, unless we changed file XY, too.

        +

        ./update.sh --ours

        +

        - Don't update, but prefetch images and exit

        +

        ./update.sh --prefetch +```

        I forgot what I changed before running update.sh

        See git log --pretty=oneline | grep -i "before update", you will have an output similar to this:

        -
        22cd00b5e28893ef9ddef3c2b5436453cc5223ab Before update on 2020-09-28_19_25_45
        -dacd4fb9b51e9e1c8a37d84485b92ffaf6c59353 Before update on 2020-08-07_13_31_31
        -
        +

        22cd00b5e28893ef9ddef3c2b5436453cc5223ab Before update on 2020-09-28_19_25_45 +dacd4fb9b51e9e1c8a37d84485b92ffaf6c59353 Before update on 2020-08-07_13_31_31

        Run git diff 22cd00b5e28893ef9ddef3c2b5436453cc5223ab to see what changed.

        Can I roll back?

        Yes.

        See the topic above, instead of a diff, you run checkout:

        -
        docker-compose down
        -# Replace commit ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab by your ID
        -git checkout 22cd00b5e28893ef9ddef3c2b5436453cc5223ab
        +

        ``` +docker-compose down

        +

        Replace commit ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab by your ID

        +

        git checkout 22cd00b5e28893ef9ddef3c2b5436453cc5223ab docker-compose pull docker-compose up -d -

        +```

        Hooks

        You can hook into the update mechanism by adding scripts called pre_commit_hook.sh and post_commit_hook.sh to your mailcows root directory. See this for more details.

        Update Cycle

        @@ -2683,7 +2851,7 @@ docker-compose up -d - + diff --git a/index.html b/index.html index 743a2d923..8a4a21fbb 100644 --- a/index.html +++ b/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2706,7 +2706,7 @@ Each container represents a single application.

        - + diff --git a/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html b/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html index 9a415ca09..72de86ffe 100644 --- a/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html +++ b/manual-guides/ClamAV/u_e-clamav-additional_dbs/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2494,21 +2494,20 @@
      60. You will need to get your_id from one of the download links, they are individual for every user
      61. Add to data/conf/clamav/freshclam.conf with replaced your_id part: -

        DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfo.hdb
        +DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfo.hdb
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfo.ign2
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/javascript.ndb
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/spam_marketing.ndb
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfohtml.hdb
         DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfoascii.hdb
        -DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfopdf.hdb
        -

        +DatabaseCustomURL https://www.securiteinfo.com/get/signatures/your_id/securiteinfopdf.hdb

      62. For free SecuriteInfo databases, download speed is limited to 300 kB/s. In data/conf/clamav/freshclam.conf, increase the default ReceiveTimeout 20 value to ReceiveTimeout 90 (time in seconds), otherwise some of the database downloads could fail because of their size.

      63. Adjust data/conf/clamav/clamd.conf to align with next settings: -

        DetectPUA yes
        +DetectPUA yes
         ExcludePUA PUA.Win.Packer
         ExcludePUA PUA.Win.Trojan.Packed
         ExcludePUA PUA.Win.Trojan.Molebox
        @@ -2520,12 +2519,11 @@ MaxRecursion 40
         MaxEmbeddedPE 100M
         MaxHTMLNormalize 50M
         MaxScriptNormalize 50M
        -MaxZipTypeRcg 50M
        -

        +MaxZipTypeRcg 50M

      64. Restart ClamAV container: -
        docker-compose restart clamd-mailcow
        -
      65. +bash +docker-compose restart clamd-mailcow

      Please note:

        @@ -2537,14 +2535,13 @@ MaxZipTypeRcg 50M

        Enable InterServer databases

        1. Add to data/conf/clamav/freshclam.conf: -
          DatabaseCustomURL http://sigs.interserver.net/interserver256.hdb
          +DatabaseCustomURL http://sigs.interserver.net/interserver256.hdb
           DatabaseCustomURL http://sigs.interserver.net/interservertopline.db
           DatabaseCustomURL http://sigs.interserver.net/shell.ldb
          -DatabaseCustomURL http://sigs.interserver.net/whitelist.fp
          -
        2. +DatabaseCustomURL http://sigs.interserver.net/whitelist.fp
        3. Restart ClamAV container: -
          docker-compose restart clamd-mailcow
          -
        4. +bash +docker-compose restart clamd-mailcow

        @@ -2665,7 +2662,7 @@ DatabaseCustomURL http://sigs.interserver.net/whitelist.fp - + diff --git a/manual-guides/ClamAV/u_e-clamav-whitelist/index.html b/manual-guides/ClamAV/u_e-clamav-whitelist/index.html index 22a0a256c..81c2c4f08 100644 --- a/manual-guides/ClamAV/u_e-clamav-whitelist/index.html +++ b/manual-guides/ClamAV/u_e-clamav-whitelist/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1870,6 +1870,13 @@ Whitelist specific ClamAV signatures + + +
      • + + docker-compose exec redis-mailcow /bin/sh + +
      @@ -2402,6 +2409,13 @@ Whitelist specific ClamAV signatures + + +
    • + + docker-compose exec redis-mailcow /bin/sh + +
    • @@ -2422,26 +2436,25 @@ -

      Whitelist

      -

      Whitelist specific ClamAV signatures

      You may find that legitimate (clean) mail is being blocked by ClamAV (Rspamd will flag the mail with VIRUS_FOUND). For instance, interactive PDF form attachments are blocked by default because the embedded Javascript code may be used for nefarious purposes. Confirm by looking at the clamd logs, e.g.:

      -
      docker-compose logs clamd-mailcow | grep "FOUND"
      -
      +

      bash +docker-compose logs clamd-mailcow | grep "FOUND"

      This line confirms that such was identified:

      -
      clamd-mailcow_1      | Sat Sep 28 07:43:24 2019 -> instream(local): PUA.Pdf.Trojan.EmbeddedJavaScript-1(e887d2ac324ce90750768b86b63d0749:363325) FOUND
      -
      +

      text +clamd-mailcow_1 | Sat Sep 28 07:43:24 2019 -> instream(local): PUA.Pdf.Trojan.EmbeddedJavaScript-1(e887d2ac324ce90750768b86b63d0749:363325) FOUND

      To whitelist this particular signature (and enable sending this type of file attached), add it to the ClamAV signature whitelist file:

      -
      echo 'PUA.Pdf.Trojan.EmbeddedJavaScript-1' >> data/conf/clamav/whitelist.ign2
      -
      +

      bash +echo 'PUA.Pdf.Trojan.EmbeddedJavaScript-1' >> data/conf/clamav/whitelist.ign2

      Then restart the clamd-mailcow service container in the mailcow UI or using docker-compose:

      -
      docker-compose restart clamd-mailcow
      -
      +

      bash +docker-compose restart clamd-mailcow

      Cleanup cached ClamAV results in Redis:

      -
      # docker-compose exec redis-mailcow  /bin/sh
      -/data # redis-cli KEYS rs_cl* | xargs redis-cli DEL
      +

      ```

      +

      docker-compose exec redis-mailcow /bin/sh

      +

      /data # redis-cli KEYS rs_cl* | xargs redis-cli DEL /data # exit -

      +```


      @@ -2561,7 +2574,7 @@ - + diff --git a/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html b/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html index ab8d68d5d..a821aac86 100644 --- a/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html +++ b/manual-guides/Docker/u_e-docker-cust_dockerfiles/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,14 +2376,11 @@

      Customize Dockerfiles

      You need to copy the override file with corresponding build tags to the mailcow: dockerized root folder (i.e. /opt/mailcow-dockerized):

      -
      cp helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml docker-compose.override.yml
      -
      +

      cp helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml docker-compose.override.yml

      Make your changes in data/Dockerfiles/$service and build the image locally:

      -
      docker build data/Dockerfiles/service -t mailcow/$service
      -
      +

      docker build data/Dockerfiles/service -t mailcow/$service

      Now auto-recreate modified containers:

      -
      docker-compose up -d
      -
      +

      docker-compose up -d


      @@ -2503,7 +2500,7 @@ - + diff --git a/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html b/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html index e852fd08a..8720d8a3e 100644 --- a/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html +++ b/manual-guides/Docker/u_e-docker-dc_bash_compl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,8 +2376,7 @@

      Docker Compose Bash Completion

      To get some sexy bash completion inside your containers simply execute the following:

      -
      curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
      -
      +

      curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose


      @@ -2497,7 +2496,7 @@ - + diff --git a/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html b/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html index f8e1601ed..8ddca8fcc 100644 --- a/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html +++ b/manual-guides/Dovecot/u_e-dovecot-any_acl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,8 +2377,7 @@

      On August the 17th, we disabled the possibility to share with "any" or "all authenticated users" by default.

      This function can be re-enabled by setting ACL_ANYONE to allow in mailcow.conf:

      -
      ACL_ANYONE=allow
      -
      +

      ACL_ANYONE=allow

      Apply the changes by running docker-compose up -d.


      @@ -2499,7 +2498,7 @@ - + diff --git a/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html b/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html index d41355634..dff2c06b4 100644 --- a/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html +++ b/manual-guides/Dovecot/u_e-dovecot-catchall_vacation/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2496,7 +2496,7 @@ - + diff --git a/manual-guides/Dovecot/u_e-dovecot-expunge/index.html b/manual-guides/Dovecot/u_e-dovecot-expunge/index.html index 323a7059a..ac494c578 100644 --- a/manual-guides/Dovecot/u_e-dovecot-expunge/index.html +++ b/manual-guides/Dovecot/u_e-dovecot-expunge/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1592,6 +1592,33 @@ + + + + + +
    • + + !/bin/bash + + +
    • + +
    • + + Path to mailcow-dockerized, e.g. /opt/mailcow-dockerized + + +
    • + +
    • + + Execute everyday at 04:00 A.M. + + + + +
    • + +
    • + + !/bin/bash + + +
    • + +
    • + + Path to mailcow-dockerized, e.g. /opt/mailcow-dockerized + + +
    • + +
    • + + Execute everyday at 04:00 A.M. + + + + +
    • + +
    • + + single user + + +
    • + +
    • + + all users + + +
    • + +
    • + + single user + + +
    • + +
    • + + all users, but obviously slower and more dangerous + + + + +
    • + +
    • + + single user + + +
    • + +
    • + + all users + + +
    • + +
    • + + single user + + +
    • + +
    • + + all users, but obviously slower and more dangerous + + +
    • @@ -2373,36 +2382,34 @@ -

      Mail crypt

      -

      Mails are stored compressed (lz4) and encrypted. The key pair can be found in crypt-vol-1.

      If you want to decode/encode existing maildir files, you can use the following script at your own risk:

      Enter Dovecot by running docker-compose exec dovecot-mailcow /bin/bash in the mailcow-dockerized location.

      -
      # Decrypt /var/vmail
      -find /var/vmail/ -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do
      -if [[ $(head -c7 "$file") == "CRYPTED" ]]; then
      +

      ```

      +

      Decrypt /var/vmail

      +

      find /var/vmail/ -type f -regextype egrep -regex '.S=.W=.*' | while read -r file; do +if [[ $(head -c7 "$file") == "CRYPTED" ]]; then doveadm fs get compress lz4:0:crypt:private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ - "$file" > "/tmp/$(basename "$file")" - if [[ -s "/tmp/$(basename "$file")" ]]; then - chmod 600 "/tmp/$(basename "$file")" - chown 5000:5000 "/tmp/$(basename "$file")" - mv "/tmp/$(basename "$file")" "$file" + "$file" > "/tmp/$(basename "$file")" + if [[ -s "/tmp/$(basename "$file")" ]]; then + chmod 600 "/tmp/$(basename "$file")" + chown 5000:5000 "/tmp/$(basename "$file")" + mv "/tmp/$(basename "$file")" "$file" else - rm "/tmp/$(basename "$file")" + rm "/tmp/$(basename "$file")" fi fi -done - -# Encrypt /var/vmail -find /var/vmail/ -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do -if [[ $(head -c7 "$file") != "CRYPTED" ]]; then +done

      +

      Encrypt /var/vmail

      +

      find /var/vmail/ -type f -regextype egrep -regex '.S=.W=.*' | while read -r file; do +if [[ $(head -c7 "$file") != "CRYPTED" ]]; then doveadm fs put crypt private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ - "$file" "$file" - chmod 600 "$file" - chown 5000:5000 "$file" + "$file" "$file" + chmod 600 "$file" + chown 5000:5000 "$file" fi done -

      +```


      @@ -2522,7 +2529,7 @@ done - + diff --git a/manual-guides/Dovecot/u_e-dovecot-more/index.html b/manual-guides/Dovecot/u_e-dovecot-more/index.html index 2341c7f69..bfb34cfa6 100644 --- a/manual-guides/Dovecot/u_e-dovecot-more/index.html +++ b/manual-guides/Dovecot/u_e-dovecot-more/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2442,25 +2442,19 @@

      doveadm quota

      The quota get and quota recalc1 commands are used to display or recalculate the current user's quota usage. The reported values are in kilobytes.

      To list the current quota status for a user / mailbox, do:

      -
      doveadm quota get -u 'mailbox@example.org'
      -
      +

      doveadm quota get -u 'mailbox@example.org'

      To list the quota storage value for all users, do:

      -
      doveadm quota get -A |grep "STORAGE"
      -
      +

      doveadm quota get -A |grep "STORAGE"

      Recalculate a single user's quota usage:

      -
      doveadm quota recalc -u 'mailbox@example.org'
      -
      +

      doveadm quota recalc -u 'mailbox@example.org'

      The doveadm search2 command is used to find messages matching your query. It can return the username, mailbox-GUID / -UID and message-GUIDs / -UIDs.

      To view the number of messages, by user, in their .Trash folder:

      -
      doveadm search -A mailbox 'Trash' | awk '{print $1}' | sort | uniq -c
      -
      +

      doveadm search -A mailbox 'Trash' | awk '{print $1}' | sort | uniq -c

      Show all messages in a user's inbox older then 90 days:

      -
      doveadm search -u 'mailbox@example.org' mailbox 'INBOX' savedbefore 90d
      -
      +

      doveadm search -u 'mailbox@example.org' mailbox 'INBOX' savedbefore 90d

      Show all messages in any folder that are older then 30 days for mailbox@example.org:

      -
      doveadm search -u 'mailbox@example.org' mailbox "*" savedbefore 30d
      -
      +

      doveadm search -u 'mailbox@example.org' mailbox "*" savedbefore 30d


        @@ -2591,7 +2585,7 @@ - + diff --git a/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html b/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html index f4ac492df..904cfda6d 100644 --- a/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html +++ b/manual-guides/Dovecot/u_e-dovecot-public_folder/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2426,28 +2426,25 @@

        Create a new public namespace "Public" and a mailbox "Develcow" inside that namespace:

        Edit or create data/conf/dovecot/extra.conf, add:

        -
        namespace {
        +

        namespace { type = public separator = / prefix = Public/ location = maildir:/var/vmail/public:INDEXPVT=~/public subscriptions = yes - mailbox "Develcow" { + mailbox "Develcow" { auto = subscribe } -} -

        +}

        :INDEXPVT=~/public can be omitted if per-user seen flags are not wanted.

        The new mailbox in the public namespace will be auto-subscribed by users.

        To allow all authenticated users access full to that new mailbox (not the whole namespace), run:

        -
        docker-compose exec dovecot-mailcow doveadm acl set -A "Public/Develcow" "authenticated" lookup read write write-seen write-deleted insert post delete expunge create
        -
        +

        docker-compose exec dovecot-mailcow doveadm acl set -A "Public/Develcow" "authenticated" lookup read write write-seen write-deleted insert post delete expunge create

        Adjust the command to your needs if you like to assign more granular rights per user (use -u user@domain instead of -A for example).

        Allow authenticated users access to the whole public namespace

        To allow all authenticated users access full access to the whole public namespace and its subfolders, create a new dovecot-acl file in the namespace root directory:

        Open/edit/create /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/public/dovecot-acl (adjust the path accordingly) to create the global ACL file with the following content:

        -
        authenticated kxeilprwts
        -
        +

        authenticated kxeilprwts

        kxeilprwts equals to lookup read write write-seen write-deleted insert post delete expunge create.

        You can use doveadm acl set -u user@domain "Public/Develcow" user=user@domain lookup read to limit access for a single user. You may also turn it around to limit access for all users to "lr" and grant only some users full access.

        See Dovecot ACL for further information about ACL.

        @@ -2570,7 +2567,7 @@ - + diff --git a/manual-guides/Dovecot/u_e-dovecot-static_master/index.html b/manual-guides/Dovecot/u_e-dovecot-static_master/index.html index 3af35dbe0..7b81c7463 100644 --- a/manual-guides/Dovecot/u_e-dovecot-static_master/index.html +++ b/manual-guides/Dovecot/u_e-dovecot-static_master/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2379,9 +2379,8 @@

        That's recommended and should not be changed.

        If you need the user to be static anyway, please specify two variables in mailcow.conf.

        Both parameters must not be empty!

        -
        DOVECOT_MASTER_USER=mymasteruser
        -DOVECOT_MASTER_PASS=mysecretpass
        -
        +

        DOVECOT_MASTER_USER=mymasteruser +DOVECOT_MASTER_PASS=mysecretpass

        Run docker-compose up -d to apply your changes.

        The static master username will be expanded to DOVECOT_MASTER_USER@mailcow.local.

        To login as test@example.org this would equal to test@example.org*mymasteruser@mailcow.local with the specified password above.

        @@ -2506,7 +2505,7 @@ No master user is required.

        - + diff --git a/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html b/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html index 0885c9b73..de5b955b8 100644 --- a/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html +++ b/manual-guides/Dovecot/u_e-dovecot-vmail-volume/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2470,41 +2470,39 @@

        Newer Docker versions seem to complain about existing volumes. You can fix this temporarily by removing the existing volume and start mailcow with the override file. But it seems to be problematic after a reboot (needs to be confirmed).

      An easy, dirty, yet stable workaround is to stop mailcow (docker-compose down), remove /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data and create a new link to your remote filesystem location, for example:

      -
      mv /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data_backup
      -ln -s /mnt/volume-xy/vmail_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data
      -
      +

      mv /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data_backup +ln -s /mnt/volume-xy/vmail_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data

      Start mailcow afterwards.


      The "old" way

      If you want to use another folder for the vmail-volume, you can create a docker-compose.override.yml file and add the following content:

      -
      version: '2.1'
      +

      version: '2.1' volumes: vmail-vol-1: driver_opts: type: none device: /data/mailcow/vmail - o: bind -

      + o: bind

      Moving an existing vmail folder:

      • Locate the current vmail folder by its "Mountpoint" attribute: docker volume inspect mailcowdockerized_vmail-vol-1
      -
      [
      +

      hl_lines="10" +[ { - "CreatedAt": "2019-06-16T22:08:34+02:00", - "Driver": "local", - "Labels": { - "com.docker.compose.project": "mailcowdockerized", - "com.docker.compose.version": "1.23.2", - "com.docker.compose.volume": "vmail-vol-1" + "CreatedAt": "2019-06-16T22:08:34+02:00", + "Driver": "local", + "Labels": { + "com.docker.compose.project": "mailcowdockerized", + "com.docker.compose.version": "1.23.2", + "com.docker.compose.volume": "vmail-vol-1" }, - "Mountpoint": "/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data", - "Name": "mailcowdockerized_vmail-vol-1", - "Options": null, - "Scope": "local" + "Mountpoint": "/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data", + "Name": "mailcowdockerized_vmail-vol-1", + "Options": null, + "Scope": "local" } -] -

      +]

      • Copy the content of the Mountpoint folder to the new location (e.g. /data/mailcow/vmail) using cp -a, rsync -a or a similar non strcuture breaking copy command
      • Stop mailcow by executing docker-compose down from within your mailcow root folder (e.g. /opt/mailcow-dockerized)
      • @@ -2631,7 +2629,7 @@ volumes: - + diff --git a/manual-guides/Nginx/u_e-nginx_custom/index.html b/manual-guides/Nginx/u_e-nginx_custom/index.html index aa34c2fb4..a3adfdbf2 100644 --- a/manual-guides/Nginx/u_e-nginx_custom/index.html +++ b/manual-guides/Nginx/u_e-nginx_custom/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2472,9 +2472,9 @@

        New site

        To create persistent (over updates) sites hosted by mailcow: dockerized, a new site configuration must be placed inside data/conf/nginx/:

        A good template to begin with:

        -
        nano data/conf/nginx/my_custom_site.conf
        -
        -
        server {
        +

        nano data/conf/nginx/my_custom_site.conf

        +

        ``` hl_lines="16" +server { ssl_certificate /etc/ssl/mail/cert.pem; ssl_certificate_key /etc/ssl/mail/key.pem; ssl_protocols TLSv1.2 TLSv1.3; @@ -2489,29 +2489,27 @@ # Location: data/web root /web; # Location: data/web/mysite.com - #root /web/mysite.com - include /etc/nginx/conf.d/listen_plain.active; + #root /web/mysite.com + include /etc/nginx/conf.d/listen_plain.active; include /etc/nginx/conf.d/listen_ssl.active; server_name mysite.example.org; - server_tokens off; - - # This allows acme to be validated even with a different web root + server_tokens off;

        +

        # This allows acme to be validated even with a different web root location ^~ /.well-known/acme-challenge/ { - default_type "text/plain"; + default_type "text/plain"; rewrite /.well-known/acme-challenge/(.*) /$1 break; root /web/.well-known/acme-challenge/; - } - - if ($scheme = http) { + }

        +

        if ($scheme = http) { return 301 https://$server_name$request_uri; } } -

        +```

        New site with proxy to a remote location

        Another example with a reverse proxy configuration:

        -
        nano data/conf/nginx/my_custom_site.conf
        -
        -
        server {
        +

        nano data/conf/nginx/my_custom_site.conf

        +

        ``` hl_lines="16 28" +server { ssl_certificate /etc/ssl/mail/cert.pem; ssl_certificate_key /etc/ssl/mail/key.pem; ssl_protocols TLSv1.2 TLSv1.3; @@ -2526,20 +2524,17 @@ root /web; include /etc/nginx/conf.d/listen_plain.active; include /etc/nginx/conf.d/listen_ssl.active; - server_name example.domain.tld; - server_tokens off; - - location ^~ /.well-known/acme-challenge/ { + server_name example.domain.tld; + server_tokens off;

        +

        location ^~ /.well-known/acme-challenge/ { allow all; - default_type "text/plain"; - } - - if ($scheme = http) { + default_type "text/plain"; + }

        +

        if ($scheme = http) { return 301 https://$host$request_uri; - } - - location / { - proxy_pass http://service:3000/; + }

        +

        location / { + proxy_pass http://service:3000/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -2547,18 +2542,16 @@ client_max_body_size 0; } } -

        +```

        Config expansion in mailcows Nginx

        The filename used for a new site is not important, as long as the filename carries a .conf extension.

        It is also possible to extend the configuration of the default file site.conf file:

        -
        nano data/conf/nginx/site.my_content.custom
        -
        +

        nano data/conf/nginx/site.my_content.custom

        This filename does not need to have a ".conf" extension but follows the pattern site.*.custom, where * is a custom name.

        If PHP is to be included in a custom site, please use the PHP-FPM listener on phpfpm:9002 or create a new listener in data/conf/phpfpm/php-fpm.d/pools.conf.

        Restart Nginx (and PHP-FPM, if a new listener was created):

        -
        docker-compose restart nginx-mailcow
        -docker-compose restart php-fpm-mailcow
        -
        +

        docker-compose restart nginx-mailcow +docker-compose restart php-fpm-mailcow


        @@ -2678,7 +2671,7 @@ docker-compose restart php-fpm-mailcow - + diff --git a/manual-guides/Nginx/u_e-nginx_webmail-site/index.html b/manual-guides/Nginx/u_e-nginx_webmail-site/index.html index 82698eb05..207ce058f 100644 --- a/manual-guides/Nginx/u_e-nginx_webmail-site/index.html +++ b/manual-guides/Nginx/u_e-nginx_webmail-site/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2378,7 +2378,8 @@

        IMPORTANT: This guide only applies to non SNI enabled configurations. The certificate path needs to be adjusted if SNI is enabled. Something like ssl_certificate,key /etc/ssl/mail/webmail.example.org/cert.pem,key.pem; will do. But: The certificate should be acquired first and only after the certificate exists a site config should be created. Nginx will fail to start if it cannot find the certificate and key.

        To create a subdomain webmail.example.org and redirect it to SOGo, you need to create a new Nginx site. Take care of "CHANGE_TO_MAILCOW_HOSTNAME"!

        nano data/conf/nginx/webmail.conf

        -
        server {
        +

        ``` hl_lines="9 17" +server { ssl_certificate /etc/ssl/mail/cert.pem; ssl_certificate_key /etc/ssl/mail/key.pem; index index.php index.html; @@ -2386,23 +2387,21 @@ root /web; include /etc/nginx/conf.d/listen_plain.active; include /etc/nginx/conf.d/listen_ssl.active; - server_name webmail.example.org; - server_tokens off; + server_name webmail.example.org; + server_tokens off; location ^~ /.well-known/acme-challenge/ { allow all; - default_type "text/plain"; + default_type "text/plain"; + }

        +

        location / { + return 301 https://CHANGE_TO_MAILCOW_HOSTNAME/SOGo; } - - location / { - return 301 https://CHANGE_TO_MAILCOW_HOSTNAME/SOGo; - } } -

        +```

        Save and restart Nginx: docker-compose restart nginx-mailcow.

        Now open mailcow.conf and find ADDITIONAL_SAN. Add webmail.example.org to this array, don't use quotes!

        -
        ADDITIONAL_SAN=webmail.example.org
        -
        +

        ADDITIONAL_SAN=webmail.example.org

        Run docker-compose up -d. See "acme-mailcow" and "nginx-mailcow" logs if anything fails.


        @@ -2523,7 +2522,7 @@ Add webmail.example.org to this array, don't use quotes!

        - + diff --git a/manual-guides/Postfix/u_e-postfix-attachment_size/index.html b/manual-guides/Postfix/u_e-postfix-attachment_size/index.html index 1a409994b..976f1479f 100644 --- a/manual-guides/Postfix/u_e-postfix-attachment_size/index.html +++ b/manual-guides/Postfix/u_e-postfix-attachment_size/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,8 +2377,7 @@

        Open data/conf/postfix/extra.cf and set the message_size_limit accordingly in bytes. See main.cf for the default value.

        Restart Postfix:

        -
        docker-compose restart postfix-mailcow
        -
        +

        docker-compose restart postfix-mailcow


        @@ -2498,7 +2497,7 @@ - + diff --git a/manual-guides/Postfix/u_e-postfix-custom_transport/index.html b/manual-guides/Postfix/u_e-postfix-custom_transport/index.html index 19820650b..0ed1c66a8 100644 --- a/manual-guides/Postfix/u_e-postfix-custom_transport/index.html +++ b/manual-guides/Postfix/u_e-postfix-custom_transport/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2497,7 +2497,7 @@ - + diff --git a/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html b/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html index f960fbf97..85ece5b4d 100644 --- a/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html +++ b/manual-guides/Postfix/u_e-postfix-disable_sender_verification/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2444,14 +2444,11 @@

        Deprecated guide (DO NOT USE ON NEWER MAILCOWS!)

        This option is not best-practice and should only be implemented when there is no other option available to achieve whatever you are trying to do.

        Simply create a file data/conf/postfix/check_sasl_access and enter the following content. This user must exist in your installation and needs to authenticate before sending mail. -

        user-to-allow-everything@example.com OK
        -

        +user-to-allow-everything@example.com OK

        Open data/conf/postfix/main.cf and find smtpd_sender_restrictions. Prepend check_sasl_access hash:/opt/postfix/conf/check_sasl_access like this: -

        smtpd_sender_restrictions = check_sasl_access hash:/opt/postfix/conf/check_sasl_access reject_authenticated_sender_login_mismatch [...]
        -

        +smtpd_sender_restrictions = check_sasl_access hash:/opt/postfix/conf/check_sasl_access reject_authenticated_sender_login_mismatch [...]

        Run postmap on check_sasl_access:

        -
        docker-compose exec postfix-mailcow postmap /opt/postfix/conf/check_sasl_access
        -
        +

        docker-compose exec postfix-mailcow postmap /opt/postfix/conf/check_sasl_access

        Restart the Postfix container.


        @@ -2572,7 +2569,7 @@ - + diff --git a/manual-guides/Postfix/u_e-postfix-extra_cf/index.html b/manual-guides/Postfix/u_e-postfix-extra_cf/index.html index 4601db6a1..2a83e0d50 100644 --- a/manual-guides/Postfix/u_e-postfix-extra_cf/index.html +++ b/manual-guides/Postfix/u_e-postfix-extra_cf/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2379,8 +2379,7 @@

        Postfix will complain about duplicate values once after starting postfix-mailcow, this is intended.

        Syslog-ng was configured to hide those warnings while Postfix is running, to not spam the log files with unnecessary information every time a service is used.

        Restart postfix-mailcow to apply your changes:

        -
        docker-compose restart postfix-mailcow
        -
        +

        docker-compose restart postfix-mailcow


        @@ -2500,7 +2499,7 @@ - + diff --git a/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html b/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html index 7280f59de..ccae17704 100644 --- a/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html +++ b/manual-guides/Postfix/u_e-postfix-pflogsumm/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,13 +2376,11 @@

        Statistics with pflogsumm

        To use pflogsumm with the default logging driver, we need to query postfix-mailcow via docker logs and direct the output to pflogsumm:

        -
        docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | pflogsumm
        -
        +

        docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | pflogsumm

        The above log output is limited to the last 24 hours.

        It is also possible to create a daily pflogsumm report via cron. Create the /etc/cron.d/pflogsumm file with the following content:

        -
        SHELL=/bin/bash
        -59 23 * * root docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | /usr/sbin/pflogsumm -d today | mail -s "Postfix Report of $(date)" postmaster@example.net
        -
        +

        SHELL=/bin/bash +59 23 * * root docker logs --since 24h $(docker ps -qf name=postfix-mailcow) | /usr/sbin/pflogsumm -d today | mail -s "Postfix Report of $(date)" postmaster@example.net

        To work, a local postfix must be installed on the server, which relays to the mailcow postfix.

        More detailed information can be found in section Post installation tasks -> Local MTA on Dockerhost.

        Based on the postfix logs of the last 24 hours, this example then sends a pflogsumm report to postmaster@example.net every day at 23:59:00.

        @@ -2506,7 +2504,7 @@ - + diff --git a/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html b/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html index 1aeac170f..4eaf99f0b 100644 --- a/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html +++ b/manual-guides/Postfix/u_e-postfix-postscreen_whitelist/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2373,19 +2382,18 @@ -

        Whitelist IP in Postscreen

        -

        IPs can be removed from Postscreen and therefore also from RBL checks in data/conf/postfix/custom_postscreen_whitelist.cidr.

        Postscreen does multiple checks to identify malicious senders. In most cases you want to whitelist an IP to exclude it from blacklist lookups.

        The format of the file is as follows:

        CIDR ACTION

        Where CIDR is a single IP address or IP range in CIDR notation, and action is either "permit" or "reject".

        Example:

        -
        +```

        The file is reloaded on the fly, postfix restart is not required.


        @@ -2506,7 +2514,7 @@ - + diff --git a/manual-guides/Postfix/u_e-postfix-relayhost/index.html b/manual-guides/Postfix/u_e-postfix-relayhost/index.html index 9cbea81fa..8cfc5ca81 100644 --- a/manual-guides/Postfix/u_e-postfix-relayhost/index.html +++ b/manual-guides/Postfix/u_e-postfix-relayhost/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2605,7 +2605,7 @@ Keep in mind the credentials will be stored in plain text.

        - + diff --git a/manual-guides/Postfix/u_e-postfix-trust_networks/index.html b/manual-guides/Postfix/u_e-postfix-trust_networks/index.html index c230c4f2d..774b7d75e 100644 --- a/manual-guides/Postfix/u_e-postfix-trust_networks/index.html +++ b/manual-guides/Postfix/u_e-postfix-trust_networks/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2475,15 +2475,13 @@

        IPv4 hosts/subnets

        To add the subnet 192.168.2.0/24 to the trusted networks you may use the following configuration, depending on your IPV4_NETWORK and IPV6_NETWORK scopes:

        Edit data/conf/postfix/extra.cf:

        -
        mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 192.168.2.0/24
        -
        +

        mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 192.168.2.0/24

        Run docker-compose restart postfix-mailcow to apply your new settings.

        IPv6 hosts/subnets

        Adding IPv6 hosts is done the same as IPv4, however the subnet needs to be placed in brackets [] with the netmask appended.

        To add the subnet 2001:db8::/32 to the trusted networks you may use the following configuration, depending on your IPV4_NETWORK and IPV6_NETWORK scopes:

        Edit data/conf/postfix/extra.cf:

        -
        mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 [2001:db8::]/32
        -
        +

        mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 [2001:db8::]/32

        Run docker-compose restart postfix-mailcow to apply your new settings.

        Info

        @@ -2608,7 +2606,7 @@ - + diff --git a/manual-guides/Redis/u_e-redis/index.html b/manual-guides/Redis/u_e-redis/index.html index 0c0f471ee..8a315fe53 100644 --- a/manual-guides/Redis/u_e-redis/index.html +++ b/manual-guides/Redis/u_e-redis/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1832,6 +1832,24 @@ +
      + + + + + + + + + +
    • + + docker-compose exec redis-mailcow redis-cli + + + -
    • - - - - @@ -2458,6 +2471,24 @@ + + + + + + + + + + +
    • + + docker-compose exec redis-mailcow redis-cli + + + -
    • - - - - @@ -2500,33 +2526,29 @@ -

      Redis

      -

      Redis is used as a key-value store for rspamd's and (some of) mailcow's settings and data. If you are unfamiliar with redis please read the introduction to redis and maybe visit this wonderful guide on how to use it.

      Client

      To connect to the redis cli execute:

      -
      docker-compose exec redis-mailcow redis-cli
      -
      +

      docker-compose exec redis-mailcow redis-cli

      Debugging

      Here are some useful commands for the redis-cli for debugging:

      MONITOR

      Listens for all requests received by the server in real time:

      -
      # docker-compose exec redis-mailcow redis-cli
      -127.0.0.1:6379> monitor
      +

      ```

      +

      docker-compose exec redis-mailcow redis-cli

      +

      127.0.0.1:6379> monitor OK -1494077286.401963 [0 172.22.1.253:41228] "SMEMBERS" "BAYES_SPAM_keys" -1494077288.292970 [0 172.22.1.253:41229] "SMEMBERS" "BAYES_SPAM_keys" +1494077286.401963 [0 172.22.1.253:41228] "SMEMBERS" "BAYES_SPAM_keys" +1494077288.292970 [0 172.22.1.253:41229] "SMEMBERS" "BAYES_SPAM_keys" [...] -

      +```

      KEYS

      Get all keys matching your pattern:

      -
      KEYS *
      -
      +

      KEYS *

      PING

      Test a connection:

      -
      127.0.0.1:6379> PING
      -PONG
      -
      +

      127.0.0.1:6379> PING +PONG

      If you want to know more, here is a cheat sheet.


      @@ -2647,7 +2669,7 @@ PONG - + diff --git a/manual-guides/Rspamd/u_e-rspamd/index.html b/manual-guides/Rspamd/u_e-rspamd/index.html index 13872ab6e..39dab39bd 100644 --- a/manual-guides/Rspamd/u_e-rspamd/index.html +++ b/manual-guides/Rspamd/u_e-rspamd/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -1838,6 +1838,26 @@ + + + + + +
    • + + Ham + + +
    • + +
    • + + Spam + + +
    • + + + + + +
    • + + Ham + + +
    • + +
    • + + Spam + + +
    • open text editor and paste data from clipboard (Ctrl+V), you should get minified CSS, save it
    • copy CSS file to mailcow server data/conf/sogo/custom-theme.css
    • edit data/conf/sogo/sogo.conf and set SOGoUIxDebugEnabled = NO;
    • append/create docker-compose.override.yml with: -
      version: '2.1'
      -
      -services:
      +```
      +version: '2.1'
    • + +

      services: sogo-mailcow: volumes: - ./data/conf/sogo/custom-theme.css:/usr/lib/GNUstep/SOGo/WebServerResources/css/theme-default.css:z -

      -
    • run docker-compose up -d
    • -
    • run docker-compose restart memcached-mailcow
    • - +`` +11. rundocker-compose up -d12. rundocker-compose restart memcached-mailcow`

      Reset to SOGo default theme

      1. checkout data/conf/sogo/custom-theme.js by executing git fetch ; git checkout origin/master data/conf/sogo/custom-theme.js data/conf/sogo/custom-theme.js
      2. find in data/conf/sogo/custom-theme.js: -
        // Apply new palettes to the default theme, remap some of the hues
        -    $mdThemingProvider.theme('default')
        -      .primaryPalette('green-cow', {
        -        'default': '400',  // background color of top toolbars
        -        'hue-1': '400',
        -        'hue-2': '600',    // background color of sidebar toolbar
        -        'hue-3': 'A700'
        +// Apply new palettes to the default theme, remap some of the hues
        +    $mdThemingProvider.theme('default')
        +      .primaryPalette('green-cow', {
        +        'default': '400',  // background color of top toolbars
        +        'hue-1': '400',
        +        'hue-2': '600',    // background color of sidebar toolbar
        +        'hue-3': 'A700'
               })
        -      .accentPalette('green', {
        -        'default': '600',  // background color of fab buttons and login screen
        -        'hue-1': '300',    // background color of center list toolbar
        -        'hue-2': '300',    // highlight color for selected mail and current day calendar
        -        'hue-3': 'A700'
        +      .accentPalette('green', {
        +        'default': '600',  // background color of fab buttons and login screen
        +        'hue-1': '300',    // background color of center list toolbar
        +        'hue-2': '300',    // highlight color for selected mail and current day calendar
        +        'hue-3': 'A700'
               })
        -      .backgroundPalette('frost-grey');
        -
        + .backgroundPalette('frost-grey'); and replace it with: -
            $mdThemingProvider.theme('default');
        -
      3. +$mdThemingProvider.theme('default');
      4. remove from docker-compose.override.yml volume mount in sogo-mailcow: -
        - ./data/conf/sogo/custom-theme.css:/usr/lib/GNUstep/SOGo/WebServerResources/css/theme-default.css:z
        -
      5. +``` +
      6. ./data/conf/sogo/custom-theme.css:/usr/lib/GNUstep/SOGo/WebServerResources/css/theme-default.css:z +```
      7. run docker-compose up -d
      8. run docker-compose restart memcached-mailcow
      @@ -2581,16 +2578,14 @@ After you replaced said file you need to restart SOGo and Memcached containers b

      Domains are usually isolated from eachother.

      You can change that by modifying data/conf/sogo/sogo.conf:

      Search... -

         // SOGoDomainsVisibility = (
      +// SOGoDomainsVisibility = (
           //  (domain1.tld, domain5.tld),
           //  (domain3.tld, domain2.tld)
      -    // );
      -
      + // ); ...and replace it by - for example:

      -
          SOGoDomainsVisibility = (
      +

      SOGoDomainsVisibility = ( (example.org, example.com, example.net) - ); -

      + );

      Restart SOGo: docker-compose restart sogo-mailcow

      Disable password changing

      Edit data/conf/sogo/sogo.conf and change SOGoPasswordChangeEnabled to NO. Please do not add a new parameter.

      @@ -2716,7 +2711,7 @@ After you replaced said file you need to restart SOGo and Memcached containers b - + diff --git a/manual-guides/Unbound/u_e-unbound-fwd/index.html b/manual-guides/Unbound/u_e-unbound-fwd/index.html index a27919b5c..e00f3a945 100644 --- a/manual-guides/Unbound/u_e-unbound-fwd/index.html +++ b/manual-guides/Unbound/u_e-unbound-fwd/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2444,18 +2444,15 @@ Important: Only DNSSEC validating DNS services will work.

      Method A, Unbound

      Edit data/conf/unbound/unbound.conf and append the following parameters:

      -
      forward-zone:
      -  name: "."
      +

      forward-zone: + name: "." forward-addr: 8.8.8.8 # DO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE - forward-addr: 8.8.4.4 # DO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE -

      + forward-addr: 8.8.4.4 # DO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE

      Restart Unbound:

      -
      docker-compose restart unbound-mailcow
      -
      +

      docker-compose restart unbound-mailcow

      Method B, Override file

      -
      cd /opt/mailcow-dockerized
      -cp helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml .
      -
      +

      cd /opt/mailcow-dockerized +cp helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml .

      Edit docker-compose.override.yml and adjust the IP.

      Run docker-compose down ; docker-compose up -d.

      @@ -2577,7 +2574,7 @@ cp helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.over - + diff --git a/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html b/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html index 0f23e7e9f..805b143ed 100644 --- a/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html +++ b/manual-guides/Watchdog/u_e-watchdog-thresholds/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2677,7 +2677,7 @@

      Watchdog uses default values for all thresholds defined in docker-compose.yml.

      The default values will work for most setups. Example: -

      - NGINX_THRESHOLD=${NGINX_THRESHOLD:-5}
      +- NGINX_THRESHOLD=${NGINX_THRESHOLD:-5}
       - UNBOUND_THRESHOLD=${UNBOUND_THRESHOLD:-5}
       - REDIS_THRESHOLD=${REDIS_THRESHOLD:-5}
       - MYSQL_THRESHOLD=${MYSQL_THRESHOLD:-5}
      @@ -2694,8 +2694,7 @@ Example:
       - RSPAMD_THRESHOLD=${RSPAMD_THRESHOLD:-5}
       - OLEFY_THRESHOLD=${OLEFY_THRESHOLD:-5}
       - MAILQ_THRESHOLD=${MAILQ_THRESHOLD:-20}
      -- MAILQ_CRIT=${MAILQ_CRIT:-30}
      -

      +- MAILQ_CRIT=${MAILQ_CRIT:-30}

      To adjust them just add necessary threshold variables (e.g. MAILQ_THRESHOLD=10) to mailcow.conf and run docker-compose up -d.

      Thresholds descriptions

      NGINX_THRESHOLD

      @@ -2851,7 +2850,7 @@ Example: - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html index 4c035d815..b8ce7efad 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-bl_wl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2502,7 +2502,7 @@ - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html index ba5873fa3..7e89804f5 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-config/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2518,7 +2518,7 @@ - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html index bdea8a332..753a1ae01 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-css/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2496,7 +2496,7 @@ - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html index 669d749ee..f60c5ea11 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-fido/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2581,7 +2581,7 @@ - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html index 73d8c1ebd..1f3a27d61 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-netfilter/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2578,7 +2578,7 @@ If this is the case, it is recommended to reset the Netfilter regex rules by cli - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html index 7bc571971..f29e917d4 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-pushover/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2506,7 +2506,7 @@ - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html index 448071061..68165b1b5 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-spamalias/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2497,7 +2497,7 @@ - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html index 906739557..f4f472dbe 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-spamfilter/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2501,7 +2501,7 @@ For a domain wide black- and whitelist please check our guide on {"base": "../../..", "features": ["navigation.top", "navigation.tracking"], "search": "../../../assets/javascripts/workers/search.2a1c317c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version.title": "Select version"}} - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html index 6cdff9a06..a28ad4eb2 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-sub_addressing/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2431,20 +2431,19 @@

      1. Move this message to a sub folder "facebook" (will be created lower case if not existing)

      2. Prepend the tag to the subject: "[facebook] Subject"

      Please note: Uppercase tags are converted to lowercase except for the first letter. If you want to keep the tag as it is, please apply the following diff and restart mailcow: -

      diff --git a/data/conf/dovecot/global_sieve_after b/data/conf/dovecot/global_sieve_after
      +diff --git a/data/conf/dovecot/global_sieve_after b/data/conf/dovecot/global_sieve_after
       index e047136e..933c4137 100644
       --- a/data/conf/dovecot/global_sieve_after
       +++ b/data/conf/dovecot/global_sieve_after
       @@ -15,7 +15,7 @@ if allof (
      -   envelope :detail :matches "to" "*",
      -   header :contains "X-Moo-Tag" "YES"
      +   envelope :detail :matches "to" "*",
      +   header :contains "X-Moo-Tag" "YES"
          ) {
      --  set :lower :upperfirst "tag" "${1}";
      -+  set "tag" "${1}";
      -   if mailboxexists "INBOX/${1}" {
      -     fileinto "INBOX/${1}";
      -   } else {
      -

      +- set :lower :upperfirst "tag" "${1}"; ++ set "tag" "${1}"; + if mailboxexists "INBOX/${1}" { + fileinto "INBOX/${1}"; + } else {


      @@ -2564,7 +2563,7 @@ index e047136e..933c4137 100644 - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html index 46160dbc8..c78659e95 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-tags/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2604,7 +2604,7 @@ To view them simply click on the small plus symbol on the left of your Domain/Ma - + diff --git a/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html b/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html index ec4900e9d..b7e83fd09 100644 --- a/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html +++ b/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2779,7 +2779,7 @@ These vendor certificates are only used to verify original hardware, not to secu - + diff --git a/manual-guides/u_e-80_to_443/index.html b/manual-guides/u_e-80_to_443/index.html index e4ee35e2a..bb73f7f19 100644 --- a/manual-guides/u_e-80_to_443/index.html +++ b/manual-guides/u_e-80_to_443/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,27 +2377,24 @@

      Do not use the config below for reverse proxy setups, please see our reverse proxy guide for this, which includes a redirect from HTTP to HTTPS.

      Open mailcow.conf and set HTTP_BIND= - if not already set.

      Create a new file data/conf/nginx/redirect.conf and add the following server config to the file:

      -
      server {
      +

      server { root /web; listen 80 default_server; listen [::]:80 default_server; include /etc/nginx/conf.d/server_name.active; - if ( $request_uri ~* "%0A|%0D" ) { return 403; } + if ( $request_uri ~* "%0A|%0D" ) { return 403; } location ^~ /.well-known/acme-challenge/ { allow all; - default_type "text/plain"; + default_type "text/plain"; } location / { return 301 https://$host$uri$is_args$args; } -} -

      +}

      In case you changed the HTTP_BIND parameter, recreate the container:

      -
      docker-compose up -d
      -
      +

      docker-compose up -d

      Otherwise restart Nginx:

      -
      docker-compose restart nginx-mailcow
      -
      +

      docker-compose restart nginx-mailcow


      @@ -2517,7 +2514,7 @@ - + diff --git a/manual-guides/u_e-autodiscover_config/index.html b/manual-guides/u_e-autodiscover_config/index.html index 9a2ce6c35..3d31dea49 100644 --- a/manual-guides/u_e-autodiscover_config/index.html +++ b/manual-guides/u_e-autodiscover_config/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2378,45 +2378,44 @@ Keep in mind, that ActiveSync should NOT be used with a desktop client.

      Open/create data/web/inc/vars.local.inc.php and add your changes to the configuration array.

      Changes will be merged with "$autodiscover_config" in data/web/inc/vars.inc.php):

      -
      <?php
      +

      <?php $autodiscover_config = array( - // General autodiscover service type: "activesync" or "imap" + // General autodiscover service type: "activesync" or "imap" // emClient uses autodiscover, but does not support ActiveSync. mailcow excludes emClient from ActiveSync. - 'autodiscoverType' => 'activesync', + 'autodiscoverType' => 'activesync', // If autodiscoverType => activesync, also use ActiveSync (EAS) for Outlook desktop clients (>= Outlook 2013 on Windows) // Outlook for Mac does not support ActiveSync - 'useEASforOutlook' => 'yes', - // Please don't use STARTTLS-enabled service ports in the "port" variable. + 'useEASforOutlook' => 'yes', + // Please don't use STARTTLS-enabled service ports in the "port" variable. // The autodiscover service will always point to SMTPS and IMAPS (TLS-wrapped services). - // The autoconfig service will additionally announce the STARTTLS-enabled ports, specified in the "tlsport" variable. - 'imap' => array( - 'server' => $mailcow_hostname, - 'port' => array_pop(explode(':', getenv('IMAPS_PORT'))), - 'tlsport' => array_pop(explode(':', getenv('IMAP_PORT'))), + // The autoconfig service will additionally announce the STARTTLS-enabled ports, specified in the "tlsport" variable. + 'imap' => array( + 'server' => $mailcow_hostname, + 'port' => array_pop(explode(':', getenv('IMAPS_PORT'))), + 'tlsport' => array_pop(explode(':', getenv('IMAP_PORT'))), ), - 'pop3' => array( - 'server' => $mailcow_hostname, - 'port' => array_pop(explode(':', getenv('POPS_PORT'))), - 'tlsport' => array_pop(explode(':', getenv('POP_PORT'))), + 'pop3' => array( + 'server' => $mailcow_hostname, + 'port' => array_pop(explode(':', getenv('POPS_PORT'))), + 'tlsport' => array_pop(explode(':', getenv('POP_PORT'))), ), - 'smtp' => array( - 'server' => $mailcow_hostname, - 'port' => array_pop(explode(':', getenv('SMTPS_PORT'))), - 'tlsport' => array_pop(explode(':', getenv('SUBMISSION_PORT'))), + 'smtp' => array( + 'server' => $mailcow_hostname, + 'port' => array_pop(explode(':', getenv('SMTPS_PORT'))), + 'tlsport' => array_pop(explode(':', getenv('SUBMISSION_PORT'))), ), - 'activesync' => array( - 'url' => 'https://'.$mailcow_hostname.($https_port == 443 ? '' : ':'.$https_port).'/Microsoft-Server-ActiveSync', + 'activesync' => array( + 'url' => 'https://'.$mailcow_hostname.($https_port == 443 ? '' : ':'.$https_port).'/Microsoft-Server-ActiveSync', ), - 'caldav' => array( - 'server' => $mailcow_hostname, - 'port' => $https_port, + 'caldav' => array( + 'server' => $mailcow_hostname, + 'port' => $https_port, ), - 'carddav' => array( - 'server' => $mailcow_hostname, - 'port' => $https_port, + 'carddav' => array( + 'server' => $mailcow_hostname, + 'port' => $https_port, ), -); -

      +);

      To always use IMAP and SMTP instead of EAS, set 'autodiscoverType' => 'imap'.

      Disable ActiveSync for Outlook desktop clients by setting "useEASforOutlook" to "no".

      @@ -2538,7 +2537,7 @@ $autodiscover_config = array( - + diff --git a/manual-guides/u_e-reeanble-weak-protocols/index.html b/manual-guides/u_e-reeanble-weak-protocols/index.html index ae9113747..69132fa79 100644 --- a/manual-guides/u_e-reeanble-weak-protocols/index.html +++ b/manual-guides/u_e-reeanble-weak-protocols/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2377,15 +2377,12 @@

      Unauthenticated mail via SMTP on port 25/tcp does still accept >= TLS 1.0 . It is better to accept a weak encryption than none at all.

      How to re-enable weak protocols?

      Edit data/conf/postfix/extra.cf:

      -
      submission_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
      -smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
      -
      +

      submission_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 +smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3

      Edit data/conf/dovecot/extra.conf:

      -
      ssl_min_protocol = TLSv1
      -
      +

      ssl_min_protocol = TLSv1

      Restart the affected services:

      -
      docker-compose restart postfix-mailcow dovecot-mailcow
      -
      +

      docker-compose restart postfix-mailcow dovecot-mailcow

      Hint: You can enable TLS 1.2 in Windows 7.


      @@ -2506,7 +2503,7 @@ smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3 - + diff --git a/manual-guides/u_e-update-hooks/index.html b/manual-guides/u_e-update-hooks/index.html index b26bda572..2716406c5 100644 --- a/manual-guides/u_e-update-hooks/index.html +++ b/manual-guides/u_e-update-hooks/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2500,7 +2500,7 @@ - + diff --git a/manual-guides/u_e-why_unbound/index.html b/manual-guides/u_e-why_unbound/index.html index 4c5442a68..d2a6a04eb 100644 --- a/manual-guides/u_e-why_unbound/index.html +++ b/manual-guides/u_e-why_unbound/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2497,7 +2497,7 @@ Using a public resolver like Googles 4x8, OpenDNS or any other shared DNS resolv - + diff --git a/models/model-acl/index.html b/models/model-acl/index.html index 4ce21a7d9..da33c3213 100644 --- a/models/model-acl/index.html +++ b/models/model-acl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2511,7 +2511,7 @@ - + diff --git a/models/model-passwd/index.html b/models/model-passwd/index.html index ef3bec762..50cb40255 100644 --- a/models/model-passwd/index.html +++ b/models/model-passwd/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2599,7 +2599,7 @@ With SOGo disabled, all hashing methods below will be able to be read by mailcow - + diff --git a/models/model-sender_rcv/index.html b/models/model-sender_rcv/index.html index ca5967acc..d9f8e0678 100644 --- a/models/model-sender_rcv/index.html +++ b/models/model-sender_rcv/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2573,7 +2573,7 @@ needs to grant you access as described above.

      - + diff --git a/post_installation/firststeps-disable_ipv6/index.html b/post_installation/firststeps-disable_ipv6/index.html index fdc98319c..55d11b89f 100644 --- a/post_installation/firststeps-disable_ipv6/index.html +++ b/post_installation/firststeps-disable_ipv6/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,8 +2380,6 @@ -

      Disable IPv6

      -

      This is ONLY recommended if you do not have an IPv6 enabled network on your host!

      If you really need to, you can disable the usage of IPv6 in the compose file. Additionally, you can also disable the startup of container "ipv6nat-mailcow", as it's not needed if you won't use IPv6.

      @@ -2381,49 +2388,45 @@ and implement your changes to the service there. Unfortunately, this right now o

      To disable IPv6 on the mailcow network, open docker-compose.yml with your favourite text editor and search for the network section (it's near the bottom of the file).

      1. Modify docker-compose.yml

      Change enable_ipv6: true to enable_ipv6: false:

      -
      networks:
      +

      networks: mailcow-network: [...] enable_ipv6: true # <<< set to false - [...] -

      + [...]

      2. Disable ipv6nat-mailcow

      To disable the ipv6nat-mailcow container as well, go to your mailcow directory and create a new file called "docker-compose.override.yml":

      NOTE: If you already have an override file, of course don't recreate it, but merge the lines below into your existing one accordingly!

      -
      # cd /opt/mailcow-dockerized
      -# touch docker-compose.override.yml
      -
      +

      ```

      +

      cd /opt/mailcow-dockerized

      +

      touch docker-compose.override.yml

      +

      ```

      Open the file in your favourite text editor and fill in the following:

      -
      version: '2.1'
      -services:
      -
      -    ipv6nat-mailcow:
      -      image: bash:latest
      -      restart: "no"
      -      entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]
      -
      +

      ``` +version: '2.1' +services:

      +
      ipv6nat-mailcow:
      +  image: bash:latest
      +  restart: "no"
      +  entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]
      +
      +

      ```

      For these changes to be effective, you need to fully stop and then restart the stack, so containers and networks are recreated:

      -
      docker-compose down
      -docker-compose up -d
      -
      +

      docker-compose down +docker-compose up -d

      3. Disable IPv6 in unbound-mailcow

      Edit data/conf/unbound/unbound.conf and set do-ip6 to "no":

      -
      server:
      +

      server: [...] do-ip6: no - [...] -

      + [...]

      Restart Unbound:

      -
      docker-compose restart unbound-mailcow
      -
      +

      docker-compose restart unbound-mailcow

      4. Disable IPv6 in postfix-mailcow

      Create data/conf/postfix/extra.cf and set smtp_address_preference to ipv4:

      -
      smtp_address_preference = ipv4
      -inet_protocols = ipv4
      -
      +

      smtp_address_preference = ipv4 +inet_protocols = ipv4

      Restart Postfix:

      -
      docker-compose restart postfix-mailcow
      -
      +

      docker-compose restart postfix-mailcow


      @@ -2543,7 +2546,7 @@ inet_protocols = ipv4 - + diff --git a/post_installation/firststeps-dmarc_reporting/index.html b/post_installation/firststeps-dmarc_reporting/index.html index 84332f8c4..2d0222b53 100644 --- a/post_installation/firststeps-dmarc_reporting/index.html +++ b/post_installation/firststeps-dmarc_reporting/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2501,44 +2501,42 @@

      Enable DMARC reporting

      Create the file data/conf/rspamd/local.d/dmarc.conf and set the following content:

      -
      reporting {
      +

      reporting { enabled = true; - email = 'noreply-dmarc@example.com'; - domain = 'example.com'; - org_name = 'Example'; - helo = 'rspamd'; - smtp = 'postfix'; + email = 'noreply-dmarc@example.com'; + domain = 'example.com'; + org_name = 'Example'; + helo = 'rspamd'; + smtp = 'postfix'; smtp_port = 25; - from_name = 'Example DMARC Report'; - msgid_from = 'rspamd.mail.example.com'; + from_name = 'Example DMARC Report'; + msgid_from = 'rspamd.mail.example.com'; max_entries = 2k; keys_expire = 2d; -} -

      +}

      Create or modify docker-compose.override.yml in the mailcow-dockerized base directory:

      -
      version: '2.1'
      -
      -services:
      +

      ``` +version: '2.1'

      +

      services: rspamd-mailcow: environment: - MASTER=${MASTER:-y} labels: - ofelia.enabled: "true" - ofelia.job-exec.rspamd_dmarc_reporting.schedule: "@every 24h" - ofelia.job-exec.rspamd_dmarc_reporting.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/bin/rspamadm dmarc_report > /var/lib/rspamd/dmarc_reports_last_log 2>&1 || exit 0\"" + ofelia.enabled: "true" + ofelia.job-exec.rspamd_dmarc_reporting.schedule: "@every 24h" + ofelia.job-exec.rspamd_dmarc_reporting.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/bin/rspamadm dmarc_report > /var/lib/rspamd/dmarc_reports_last_log 2>&1 || exit 0\"" ofelia-mailcow: depends_on: - rspamd-mailcow -

      +```

      Run docker-compose up -d

      Send a copy reports to yourself

      To receive a hidden copy of reports generated by Rspamd you can set a bcc_addrs list in the reporting config section of data/conf/rspamd/local.d/dmarc.conf:

      -
      reporting {
      +

      reporting { enabled = true; - email = 'noreply-dmarc@example.com'; - bcc_addrs = ["noreply-dmarc@example.com","parsedmarc@example.com"]; -[...] -

      + email = 'noreply-dmarc@example.com'; + bcc_addrs = ["noreply-dmarc@example.com","parsedmarc@example.com"]; +[...]

      Rspamd will load changes in real time, so you won't need to restart the container at this point.

      This can be useful if you...

        @@ -2547,21 +2545,16 @@ services:

      Troubleshooting

      Check when the report schedule last ran:

      -
      docker-compose exec rspamd-mailcow date -r /var/lib/rspamd/dmarc_reports_last_log
      -
      +

      docker-compose exec rspamd-mailcow date -r /var/lib/rspamd/dmarc_reports_last_log

      See the latest report output:

      -
      docker-compose exec rspamd-mailcow cat /var/lib/rspamd/dmarc_reports_last_log
      -
      +

      docker-compose exec rspamd-mailcow cat /var/lib/rspamd/dmarc_reports_last_log

      Manually trigger a DMARC report:

      -
      docker-compose exec rspamd-mailcow rspamadm dmarc_report
      -
      +

      docker-compose exec rspamd-mailcow rspamadm dmarc_report

      Validate that Rspamd has recorded data in Redis: Change 20220428 to date which you interested in.

      -

      docker-compose exec redis-mailcow redis-cli SMEMBERS "dmarc_idx;20220428"
      -
      +

      docker-compose exec redis-mailcow redis-cli SMEMBERS "dmarc_idx;20220428" Take one of the lines from output you interested in and request it, f.e.: -

      docker-compose exec redis-mailcow redis-cli ZRANGE "dmarc_rpt;microsoft.com;mailto:d@rua.agari.com;20220428" 0 49
      -

      +docker-compose exec redis-mailcow redis-cli ZRANGE "dmarc_rpt;microsoft.com;mailto:d@rua.agari.com;20220428" 0 49

      Change DMARC reporting frequency

      In the example above reports are sent once every 24 hours.

      Olefia schedule has same implementation as cron in Go, supported syntax described at cron Documentation

      @@ -2709,7 +2702,7 @@ Take one of the lines from output you interested in and request it, f.e.: - + diff --git a/post_installation/firststeps-ip_bindings/index.html b/post_installation/firststeps-ip_bindings/index.html index 8f7f843e4..c67aa1487 100644 --- a/post_installation/firststeps-ip_bindings/index.html +++ b/post_installation/firststeps-ip_bindings/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -530,10 +530,65 @@
    • + + For technical reasons, http bindings are a bit different from other service bindings. + + +
    • + +
    • + + You will find the following variables, separated by a bind address and its port: + + +
    • + +
    • + + Example: HTTP_BIND=1.2.3.4 + + +
    • + +
    • + + Other services are bound by using the following format: + + +
    • + +
    • + + SMTP_PORT=1.2.3.4:25 will bind SMTP to the IP 1.2.3.4 on port 25 + + +
    • + +
    • + + Important! Specifying an IPv4 address will skip all IPv6 bindings since Docker 20.x. + + +
    • + +
    • + + doveadm, SQL as well as Solr are bound to local ports only, please do not change that, unless you know what you are doing. + + + +
    • @@ -2410,10 +2465,65 @@
    • + + For technical reasons, http bindings are a bit different from other service bindings. + + +
    • + +
    • + + You will find the following variables, separated by a bind address and its port: + + +
    • + +
    • + + Example: HTTP_BIND=1.2.3.4 + + +
    • + +
    • + + Other services are bound by using the following format: + + +
    • + +
    • + + SMTP_PORT=1.2.3.4:25 will bind SMTP to the IP 1.2.3.4 on port 25 + + +
    • + +
    • + + Important! Specifying an IPv4 address will skip all IPv6 bindings since Docker 20.x. + + +
    • + +
    • + + doveadm, SQL as well as Solr are bound to local ports only, please do not change that, unless you know what you are doing. + + + +
    • @@ -2434,29 +2544,25 @@ -

      IP bindings

      -

      Warning

      Changing the binding does not affect source NAT. See SNAT for required steps.

      IPv4 binding

      To adjust one or multiple IPv4 bindings, open mailcow.conf and edit one, multiple or all variables as per your needs:

      -
      # For technical reasons, http bindings are a bit different from other service bindings.
      -# You will find the following variables, separated by a bind address and its port:
      -# Example: HTTP_BIND=1.2.3.4
      -
      -HTTP_PORT=80
      +

      ```

      +

      For technical reasons, http bindings are a bit different from other service bindings.

      +

      You will find the following variables, separated by a bind address and its port:

      +

      Example: HTTP_BIND=1.2.3.4

      +

      HTTP_PORT=80 HTTP_BIND= HTTPS_PORT=443 -HTTPS_BIND= - -# Other services are bound by using the following format: -# SMTP_PORT=1.2.3.4:25 will bind SMTP to the IP 1.2.3.4 on port 25 -# Important! Specifying an IPv4 address will skip all IPv6 bindings since Docker 20.x. -# doveadm, SQL as well as Solr are bound to local ports only, please do not change that, unless you know what you are doing. - -SMTP_PORT=25 +HTTPS_BIND=

      +

      Other services are bound by using the following format:

      +

      SMTP_PORT=1.2.3.4:25 will bind SMTP to the IP 1.2.3.4 on port 25

      +

      Important! Specifying an IPv4 address will skip all IPv6 bindings since Docker 20.x.

      +

      doveadm, SQL as well as Solr are bound to local ports only, please do not change that, unless you know what you are doing.

      +

      SMTP_PORT=25 SMTPS_PORT=465 SUBMISSION_PORT=587 IMAP_PORT=143 @@ -2467,35 +2573,36 @@ SIEVE_PORT=4190 DOVEADM_PORT=127.0.0.1:19991 SQL_PORT=127.0.0.1:13306 SOLR_PORT=127.0.0.1:18983 -

      +```

      To apply your changes, run docker-compose down followed by docker-compose up -d.

      IPv6 binding

      Changing IPv6 bindings is different from IPv4. Again, this has a technical background.

      A docker-compose.override.yml file will be used instead of editing the docker-compose.yml file directly. This is to maintain updatability, as the docker-compose.yml file gets updated regularly and your changes will most likely be overwritten.

      Edit to create a file docker-compose.override.yml with the following content. Its content will be merged with the productive docker-compose.yml file.

      An imaginary IPv6 2a00:dead:beef::abc is given. The first suffix :PORT1 defines the external port, while the second suffix :PORT2 routes to the corresponding port inside the container and must not be changed.

      -
      version: '2.1'
      -services:
      +

      ``` +version: '2.1' +services:

      +
      dovecot-mailcow:
      +  ports:
      +    - '2a00:dead:beef::abc:143:143'
      +    - '2a00:dead:beef::abc:993:993'
      +    - '2a00:dead:beef::abc:110:110'
      +    - '2a00:dead:beef::abc:995:995'
      +    - '2a00:dead:beef::abc:4190:4190'
       
      -    dovecot-mailcow:
      -      ports:
      -        - '2a00:dead:beef::abc:143:143'
      -        - '2a00:dead:beef::abc:993:993'
      -        - '2a00:dead:beef::abc:110:110'
      -        - '2a00:dead:beef::abc:995:995'
      -        - '2a00:dead:beef::abc:4190:4190'
      +postfix-mailcow:
      +  ports:
      +    - '2a00:dead:beef::abc:25:25'
      +    - '2a00:dead:beef::abc:465:465'
      +    - '2a00:dead:beef::abc:587:587'
       
      -    postfix-mailcow:
      -      ports:
      -        - '2a00:dead:beef::abc:25:25'
      -        - '2a00:dead:beef::abc:465:465'
      -        - '2a00:dead:beef::abc:587:587'
      -
      -    nginx-mailcow:
      -      ports:
      -        - '2a00:dead:beef::abc:80:80'
      -        - '2a00:dead:beef::abc:443:443'
      -
      +nginx-mailcow: + ports: + - '2a00:dead:beef::abc:80:80' + - '2a00:dead:beef::abc:443:443' + +

      ```

      To apply your changes, run docker-compose down followed by docker-compose up -d.


      @@ -2616,7 +2723,7 @@ services: - + diff --git a/post_installation/firststeps-local_mta/index.html b/post_installation/firststeps-local_mta/index.html index d3552451a..8957871cb 100644 --- a/post_installation/firststeps-local_mta/index.html +++ b/post_installation/firststeps-local_mta/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@ @@ -2371,19 +2380,17 @@ -

      Local MTA on Docker host

      -

      The easiest option would be to disable the listener on port 25/tcp.

      Postfix users disable the listener by commenting the following line (starting with smtp or 25) in /etc/postfix/master.cf: -

      #smtp      inet  n       -       -       -       -       smtpd
      -

      +```

      +

      smtp inet n - - - - smtpd

      +

      ```

      Furthermore, to relay over a dockerized mailcow, you may want to add 172.22.1.1 as relayhost and remove the Docker interface from "inet_interfaces":

      -
      postconf -e 'relayhost = 172.22.1.1'
      -postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128"
      -postconf -e "inet_interfaces = loopback-only"
      -postconf -e "relay_transport = relay"
      -postconf -e "default_transport = smtp"
      -
      +

      postconf -e 'relayhost = 172.22.1.1' +postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128" +postconf -e "inet_interfaces = loopback-only" +postconf -e "relay_transport = relay" +postconf -e "default_transport = smtp"

      Now it is important to not have the same FQDN in myhostname as you use for your dockerized mailcow. Check your local (non-Docker) Postfix' main.cf for myhostname and set it to something different, for example local.my.fqdn.tld.

      "172.22.1.1" is the mailcow created network gateway in Docker. Relaying over this interface is necessary (instead of - for example - relaying directly over ${MAILCOW_HOSTNAME}) to relay over a known internal network.

      @@ -2507,7 +2514,7 @@ Relaying over this interface is necessary (instead of - for example - relaying d - + diff --git a/post_installation/firststeps-logging/index.html b/post_installation/firststeps-logging/index.html index d0a2b5b43..07c687848 100644 --- a/post_installation/firststeps-logging/index.html +++ b/post_installation/firststeps-logging/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -572,6 +572,33 @@ + + + + + +
    • + + For Rsyslog only: + + +
    • + +
    • + + To move local3 input to /var/log/mailcow.log and stop processing, create a file "/etc/rsyslog.d/docker.conf": + + +
    • + +
    • + + Restart rsyslog afterwards. + + + + +
    • + +
    • + + For Rsyslog only: + + +
    • + +
    • + + To move local3 input to /var/log/mailcow.log and stop processing, create a file "/etc/rsyslog.d/docker.conf": + + +
    • + +
    • + + Restart rsyslog afterwards. + + +
    • + + !/bin/bash + + + +
    • @@ -2490,16 +2516,14 @@ -

      Reverse Proxy

      -

      You don't need to change the Nginx site that comes with mailcow: dockerized. mailcow: dockerized trusts the default gateway IP 172.22.1.1 as proxy.

      1. Make sure you change HTTP_BIND and HTTPS_BIND in mailcow.conf to a local address and set the ports accordingly, for example: -

      HTTP_BIND=127.0.0.1
      -HTTP_PORT=8080
      -HTTPS_BIND=127.0.0.1
      -HTTPS_PORT=8443
      -

      +bash +HTTP_BIND=127.0.0.1 +HTTP_PORT=8080 +HTTPS_BIND=127.0.0.1 +HTTPS_PORT=8443

      This will also change the bindings inside the Nginx container! This is important, if you decide to use a proxy within Docker.

      IMPORTANT: Do not use port 8081, 9081 or 65510!

      Recreate affected containers by running docker-compose up -d.

      @@ -2528,81 +2552,73 @@ On many servers logrotate will reload the webserver daily anyway.

      2. Configure your local webserver as reverse proxy:

      Apache 2.4

      Required modules: -

      a2enmod rewrite proxy proxy_http headers ssl
      -

      +a2enmod rewrite proxy proxy_http headers ssl

      Let's Encrypt will follow our rewrite, certificate requests in mailcow will work fine.

      Take care of highlighted lines.

      -
      <VirtualHost *:80>
      -  ServerName CHANGE_TO_MAILCOW_HOSTNAME
      -  ServerAlias autodiscover.*
      -  ServerAlias autoconfig.*
      -  RewriteEngine on
      -
      -  RewriteCond %{HTTPS} off
      -  RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R=301,L]
      -
      -  ProxyPass / http://127.0.0.1:8080/
      -  ProxyPassReverse / http://127.0.0.1:8080/
      -  ProxyPreserveHost On
      -  ProxyAddHeaders On
      -  RequestHeader set X-Forwarded-Proto "http"
      -</VirtualHost>
      -<VirtualHost *:443>
      -  ServerName CHANGE_TO_MAILCOW_HOSTNAME
      -  ServerAlias autodiscover.*
      -  ServerAlias autoconfig.*
      -
      -  # You should proxy to a plain HTTP session to offload SSL processing
      -  ProxyPass /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync connectiontimeout=4000
      -  ProxyPassReverse /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync
      -  ProxyPass / http://127.0.0.1:8080/
      -  ProxyPassReverse / http://127.0.0.1:8080/
      -  ProxyPreserveHost On
      -  ProxyAddHeaders On
      -  RequestHeader set X-Forwarded-Proto "https"
      -
      -  SSLCertificateFile MAILCOW_PATH/data/assets/ssl/cert.pem
      -  SSLCertificateKeyFile MAILCOW_PATH/data/assets/ssl/key.pem
      -
      -  # If you plan to proxy to a HTTPS host:
      -  #SSLProxyEngine On
      -
      -  # If you plan to proxy to an untrusted HTTPS host:
      -  #SSLProxyVerify none
      -  #SSLProxyCheckPeerCN off
      -  #SSLProxyCheckPeerName off
      -  #SSLProxyCheckPeerExpire off
      -</VirtualHost>
      -
      +

      ``` apache hl_lines="2 10 11 17 22 23 24 25 30 31" + + ServerName CHANGE_TO_MAILCOW_HOSTNAME + ServerAlias autodiscover.* + ServerAlias autoconfig.* + RewriteEngine on

      +

      RewriteCond %{HTTPS} off + RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R=301,L]

      +

      ProxyPass / http://127.0.0.1:8080/ + ProxyPassReverse / http://127.0.0.1:8080/ + ProxyPreserveHost On + ProxyAddHeaders On + RequestHeader set X-Forwarded-Proto "http" + + + ServerName CHANGE_TO_MAILCOW_HOSTNAME + ServerAlias autodiscover.* + ServerAlias autoconfig.*

      +

      # You should proxy to a plain HTTP session to offload SSL processing + ProxyPass /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync connectiontimeout=4000 + ProxyPassReverse /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync + ProxyPass / http://127.0.0.1:8080/ + ProxyPassReverse / http://127.0.0.1:8080/ + ProxyPreserveHost On + ProxyAddHeaders On + RequestHeader set X-Forwarded-Proto "https"

      +

      SSLCertificateFile MAILCOW_PATH/data/assets/ssl/cert.pem + SSLCertificateKeyFile MAILCOW_PATH/data/assets/ssl/key.pem

      +

      # If you plan to proxy to a HTTPS host: + #SSLProxyEngine On

      +

      # If you plan to proxy to an untrusted HTTPS host: + #SSLProxyVerify none + #SSLProxyCheckPeerCN off + #SSLProxyCheckPeerName off + #SSLProxyCheckPeerExpire off + +```

      Nginx

      Let's Encrypt will follow our rewrite, certificate requests will work fine.

      Take care of highlighted lines.

      -
      server {
      +

      ``` hl_lines="4 10 12 13 25 39" +server { listen 80 default_server; listen [::]:80 default_server; - server_name CHANGE_TO_MAILCOW_HOSTNAME autodiscover.* autoconfig.*; - return 301 https://$host$request_uri; + server_name CHANGE_TO_MAILCOW_HOSTNAME autodiscover.* autoconfig.; + return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; - server_name CHANGE_TO_MAILCOW_HOSTNAME autodiscover.* autoconfig.*; - - ssl_certificate MAILCOW_PATH/data/assets/ssl/cert.pem; - ssl_certificate_key MAILCOW_PATH/data/assets/ssl/key.pem; - ssl_session_timeout 1d; + server_name CHANGE_TO_MAILCOW_HOSTNAME autodiscover. autoconfig.*;

      +

      ssl_certificate MAILCOW_PATH/data/assets/ssl/cert.pem; + ssl_certificate_key MAILCOW_PATH/data/assets/ssl/key.pem; + ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; - ssl_session_tickets off; - - # See https://ssl-config.mozilla.org/#server=nginx for the latest ssl settings recommendations + ssl_session_tickets off;

      +

      # See https://ssl-config.mozilla.org/#server=nginx for the latest ssl settings recommendations # An example config is given below ssl_protocols TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5:!SHA1:!kRSA; - ssl_prefer_server_ciphers off; - - location /Microsoft-Server-ActiveSync { - proxy_pass http://127.0.0.1:8080/Microsoft-Server-ActiveSync; - proxy_set_header Host $http_host; + ssl_prefer_server_ciphers off;

      +

      location /Microsoft-Server-ActiveSync { + proxy_pass http://127.0.0.1:8080/Microsoft-Server-ActiveSync; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; @@ -2612,39 +2628,38 @@ server { proxy_buffers 64 512k; # Needed since the 2022-04 Update for SOGo client_body_buffer_size 512k; client_max_body_size 0; - } - - location / { - proxy_pass http://127.0.0.1:8080/; - proxy_set_header Host $http_host; + }

      +

      location / { + proxy_pass http://127.0.0.1:8080/; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 0; # The following Proxy Buffers has to be set if you want to use SOGo after the 2022-04 (April 2022) Update - # Otherwise a Login will fail like this: https://github.com/mailcow/mailcow-dockerized/issues/4537 + # Otherwise a Login will fail like this: https://github.com/mailcow/mailcow-dockerized/issues/4537 proxy_buffer_size 128k; proxy_buffers 64 512k; proxy_busy_buffers_size 512k; } } -

      +```

      HAProxy (community supported)

      Warning

      This is an unsupported community contribution. Feel free to provide fixes.

      Important/Fixme: This example only forwards HTTPS traffic and does not use mailcows built-in ACME client.

      -
      frontend https-in
      +

      ``` +frontend https-in bind :::443 v4v6 ssl crt mailcow.pem - default_backend mailcow - -backend mailcow + default_backend mailcow

      +

      backend mailcow option forwardfor http-request set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Proto http if !{ ssl_fc } server mailcow 127.0.0.1:8080 check -

      +```

      Traefik v2 (community supported)

      Warning

      @@ -2655,50 +2670,49 @@ backend mailcow

      So, first of all, we are going to disable the acme-mailcow container since we'll use the certs that traefik will provide us. For this we'll have to set SKIP_LETS_ENCRYPT=y on our mailcow.conf, and run docker-compose up -d to apply the changes.

      Then we'll create a docker-compose.override.yml file in order to override the main docker-compose.yml found in your mailcow root folder.

      -
      version: '2.1'
      -
      -services:
      -    nginx-mailcow:
      -      networks:
      -        # add Traefik's network
      -        web:
      -      labels:
      -        - traefik.enable=true
      -        # Creates a router called "moo" for the container, and sets up a rule to link the container to certain rule,
      -        #   in this case, a Host rule with our MAILCOW_HOSTNAME var.
      -        - traefik.http.routers.moo.rule=Host(`${MAILCOW_HOSTNAME}`)
      -        # Enables tls over the router we created before.
      -        - traefik.http.routers.moo.tls=true
      -        # Specifies which kind of cert resolver we'll use, in this case le (Lets Encrypt).
      -        - traefik.http.routers.moo.tls.certresolver=le
      -        # Creates a service called "moo" for the container, and specifies which internal port of the container
      -        #   should traefik route the incoming data to.
      -        - traefik.http.services.moo.loadbalancer.server.port=${HTTP_PORT}
      -        # Specifies which entrypoint (external port) should traefik listen to, for this container.
      -        #   websecure being port 443, check the traefik.toml file liked above.
      -        - traefik.http.routers.moo.entrypoints=websecure
      -        # Make sure traefik uses the web network, not the mailcowdockerized_mailcow-network
      -        - traefik.docker.network=web
      -
      -    certdumper:
      -        image: humenius/traefik-certs-dumper
      -        container_name: traefik_certdumper
      -        network_mode: none
      -        volumes:
      -          # mount the folder which contains Traefik's `acme.json' file
      -          #   in this case Traefik is started from its own docker-compose in ../traefik
      -          - ../traefik/data:/traefik:ro
      -          # mount mailcow's SSL folder
      -          - ./data/assets/ssl/:/output:rw
      -        restart: always
      -        environment:
      -          # only change this, if you're using another domain for mailcow's web frontend compared to the standard config
      -          - DOMAIN=${MAILCOW_HOSTNAME}
      -
      -networks:
      -  web:
      -    external: true
      -
      +

      ```yaml +version: '2.1'

      +

      services: + nginx-mailcow: + networks: + # add Traefik's network + web: + labels: + - traefik.enable=true + # Creates a router called "moo" for the container, and sets up a rule to link the container to certain rule, + # in this case, a Host rule with our MAILCOW_HOSTNAME var. + - traefik.http.routers.moo.rule=Host(${MAILCOW_HOSTNAME}) + # Enables tls over the router we created before. + - traefik.http.routers.moo.tls=true + # Specifies which kind of cert resolver we'll use, in this case le (Lets Encrypt). + - traefik.http.routers.moo.tls.certresolver=le + # Creates a service called "moo" for the container, and specifies which internal port of the container + # should traefik route the incoming data to. + - traefik.http.services.moo.loadbalancer.server.port=${HTTP_PORT} + # Specifies which entrypoint (external port) should traefik listen to, for this container. + # websecure being port 443, check the traefik.toml file liked above. + - traefik.http.routers.moo.entrypoints=websecure + # Make sure traefik uses the web network, not the mailcowdockerized_mailcow-network + - traefik.docker.network=web

      +
      certdumper:
      +    image: humenius/traefik-certs-dumper
      +    container_name: traefik_certdumper
      +    network_mode: none
      +    volumes:
      +      # mount the folder which contains Traefik's `acme.json' file
      +      #   in this case Traefik is started from its own docker-compose in ../traefik
      +      - ../traefik/data:/traefik:ro
      +      # mount mailcow's SSL folder
      +      - ./data/assets/ssl/:/output:rw
      +    restart: always
      +    environment:
      +      # only change this, if you're using another domain for mailcow's web frontend compared to the standard config
      +      - DOMAIN=${MAILCOW_HOSTNAME}
      +
      +

      networks: + web: + external: true +```

      Start the new containers with docker-compose up -d.

      Now, there's only one thing left to do, which is setup the certs so that the mail services can use them as well, since Traefik 2 uses an acme v2 format to save ALL the license from all the domains we have, we'll need to find a way to dump the certs, lucky we have this tiny container which grabs the acme.json file trough a volume, and a variable DOMAIN=example.org, and with these, the container will output the cert.pem and key.pem files, for this we'll simply run the traefik-certs-dumper container binding the /traefik volume to the folder where our acme.json is saved, bind the /output volume to our mailcow data/assets/ssl/ folder, and set up the DOMAIN=example.org variable to the domain we want the certs dumped from.

      This container will watch over the acme.json file for any changes, and regenerate the cert.pem and key.pem files directly into data/assets/ssl/ being the path binded to the container's /output path.

      @@ -2708,18 +2722,18 @@ For this we'll have to set SKIP_LETS_ENCRYPT=y on our mailcow

      Optional: Post-hook script for non-mailcow ACME clients

      Using a local certbot (or any other ACME client) requires to restart some containers, you can do this with a post-hook script. Make sure you change the paths accordingly: -

      #!/bin/bash
      -cp /etc/letsencrypt/live/my.domain.tld/fullchain.pem /opt/mailcow-dockerized/data/assets/ssl/cert.pem
      +```

      +

      !/bin/bash

      +

      cp /etc/letsencrypt/live/my.domain.tld/fullchain.pem /opt/mailcow-dockerized/data/assets/ssl/cert.pem cp /etc/letsencrypt/live/my.domain.tld/privkey.pem /opt/mailcow-dockerized/data/assets/ssl/key.pem postfix_c=$(docker ps -qaf name=postfix-mailcow) dovecot_c=$(docker ps -qaf name=dovecot-mailcow) nginx_c=$(docker ps -qaf name=nginx-mailcow) docker restart ${postfix_c} ${dovecot_c} ${nginx_c} -

      +```

      Adding additional server names for mailcow UI

      If you plan to use a server name that is not MAILCOW_HOSTNAME in your reverse proxy, make sure to populate that name in mailcow.conf via ADDITIONAL_SERVER_NAMES first. Names must be separated by commas and must not contain spaces. If you skip this step, mailcow may respond to your reverse proxy with an incorrect site.

      -
      ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld
      -
      +

      ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld

      Run docker-compose up -d to apply.


      @@ -2840,7 +2854,7 @@ docker restart ${postfix_c} ${dovecot_c} ${nginx_c} - + diff --git a/post_installation/firststeps-rspamd_ui/index.html b/post_installation/firststeps-rspamd_ui/index.html index 674c1dd36..9237bc779 100644 --- a/post_installation/firststeps-rspamd_ui/index.html +++ b/post_installation/firststeps-rspamd_ui/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2500,7 +2500,7 @@ - + diff --git a/post_installation/firststeps-snat/index.html b/post_installation/firststeps-snat/index.html index 0c410d6f2..a08f4011d 100644 --- a/post_installation/firststeps-snat/index.html +++ b/post_installation/firststeps-snat/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@
      @@ -564,6 +569,8 @@ + + SNAT @@ -2354,6 +2361,8 @@ + +
      @@ -2371,17 +2380,15 @@ -

      SNAT

      -

      SNAT is used to change the source address of the packets sent by mailcow. It can be used to change the outgoing IP address on systems with multiple IP addresses.

      Open mailcow.conf, set either or both of the following parameters:

      -
      # Use this IPv4 for outgoing connections (SNAT)
      -SNAT_TO_SOURCE=1.2.3.4
      -
      -# Use this IPv6 for outgoing connections (SNAT)
      -SNAT6_TO_SOURCE=dead:beef
      -
      +

      ```

      +

      Use this IPv4 for outgoing connections (SNAT)

      +

      SNAT_TO_SOURCE=1.2.3.4

      +

      Use this IPv6 for outgoing connections (SNAT)

      +

      SNAT6_TO_SOURCE=dead:beef +```

      Run docker-compose up -d.

      The values are read by netfilter-mailcow. netfilter-mailcow will make sure, the post-routing rules are on position 1 in the netfilter table. It does automatically delete and re-create them if they are found on another position than 1.

      Check the output of docker-compose logs --tail=200 netfilter-mailcow to ensure the SNAT settings have been applied.

      @@ -2504,7 +2511,7 @@ SNAT6_TO_SOURCE=dead:beef - + diff --git a/post_installation/firststeps-ssl/index.html b/post_installation/firststeps-ssl/index.html index e083a0256..b6529b13d 100644 --- a/post_installation/firststeps-ssl/index.html +++ b/post_installation/firststeps-ssl/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -502,6 +502,19 @@ + + + + + +
    • + + Now check the logs for a renewal + + + +
    • + +
    • + + Connect via SMTP (587) + + +
    • + +
    • + + Connect via IMAP (143) + + +
    • + +
    • + + Connect via HTTPS (443) + +
    • @@ -2506,6 +2540,19 @@ + + + + + +
    • + + Now check the logs for a renewal + + + +
    • + +
    • + + Connect via SMTP (587) + + +
    • + +
    • + + Connect via IMAP (143) + + +
    • + +
    • + + Connect via HTTPS (443) + +
    • @@ -2598,8 +2666,6 @@ -

      Advanced SSL

      -

      Let's Encrypt (out-of-the-box)

      The "acme-mailcow" container will try to obtain a LE certificate for ${MAILCOW_HOSTNAME}, autodiscover.ADDED_MAIL_DOMAIN and autoconfig.ADDED_MAIL_DOMAIN.

      @@ -2614,8 +2680,7 @@

      Additional domain names

      Edit "mailcow.conf" and add a parameter ADDITIONAL_SAN like this:

      Do not use quotes (") and do not use spaces between the names!

      -
      ADDITIONAL_SAN=smtp.*,cert1.example.com,cert2.example.org,whatever.*
      -
      +

      ADDITIONAL_SAN=smtp.*,cert1.example.com,cert2.example.org,whatever.*

      Each name will be validated against its IPv6 address or - if IPv6 is not configured in your domain - IPv4 address.

      A wildcard name like smtp.* will try to obtain a smtp.DOMAIN_NAME SAN for each domain added to mailcow.

      Run docker-compose up -d to recreate affected containers automatically.

      @@ -2624,17 +2689,17 @@

      Using names other name MAILCOW_HOSTNAME to access the mailcow UI may need further configuration.

      If you plan to use a server name that is not MAILCOW_HOSTNAME to access the mailcow UI (for example by adding mail.* to ADDITIONAL_SAN make sure to populate that name in mailcow.conf via ADDITIONAL_SERVER_NAMES. Names must be separated by commas and must not contain spaces. If you skip this step, mailcow may respond with an incorrect site.

      -
      ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld
      -
      +

      ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld

      Run docker-compose up -d to apply.

      Force renewal

      To force a renewal, you need to create a file named force_renew and restart the acme-mailcow container:

      -
      cd /opt/mailcow-dockerized
      +

      ``` +cd /opt/mailcow-dockerized touch data/assets/ssl/force_renew -docker-compose restart acme-mailcow -# Now check the logs for a renewal -docker-compose logs --tail=200 -f acme-mailcow -

      +docker-compose restart acme-mailcow

      +

      Now check the logs for a renewal

      +

      docker-compose logs --tail=200 -f acme-mailcow +```

      The file will be deleted automatically.

      Validation errors and how to skip validation

      You can skip the IP verification by setting SKIP_IP_CHECK=y in mailcow.conf (no quotes). Be warned that a misconfiguration will get you ratelimited by Let's Encrypt! This is primarily useful for multi-IP setups where the IP check would return the incorrect source IP address. Due to using dynamic IPs for acme-mailcow, source NAT is not consistent over restarts.

      @@ -2681,35 +2746,33 @@ You should make sure these clients use the MAILCOW_HOSTNAME for sec

      To use your own certificates, just save the combined certificate (containing the certificate and intermediate CA/CA if any) to data/assets/ssl/cert.pem and the corresponding key to data/assets/ssl/key.pem.

      IMPORTANT: Do not use symbolic links! Make sure you copy the certificates and do not link them to data/assets/ssl.

      Restart affected services afterwards:

      -
      docker restart $(docker ps -qaf name=postfix-mailcow)
      +

      docker restart $(docker ps -qaf name=postfix-mailcow) docker restart $(docker ps -qaf name=nginx-mailcow) -docker restart $(docker ps -qaf name=dovecot-mailcow) -

      +docker restart $(docker ps -qaf name=dovecot-mailcow)

      See Post-hook script for non-mailcow ACME clients for a full example script.

      Test against staging ACME directory

      Edit mailcow.conf and add LE_STAGING=y.

      Run docker-compose up -d to activate your changes.

      Custom directory URL

      Edit mailcow.conf and add the corresponding directory URL to the new variable DIRECTORY_URL:

      -
      DIRECTORY_URL=https://acme-custom-v9000.api.letsencrypt.org/directory
      -
      +

      DIRECTORY_URL=https://acme-custom-v9000.api.letsencrypt.org/directory

      You cannot use LE_STAGING with DIRECTORY_URL. If both are set, only LE_STAGING is used.

      Run docker-compose up -d to activate your changes.

      Check your configuration

      Run docker-compose logs acme-mailcow to find out why a validation fails.

      To check if nginx serves the correct certificate, simply use a browser of your choice and check the displayed certificate.

      To check the certificate served by Postfix, Dovecot and Nginx we will use openssl:

      -
      # Connect via SMTP (587)
      -echo "Q" | openssl s_client -starttls smtp -crlf -connect mx.mailcow.email:587
      -# Connect via IMAP (143)
      -echo "Q" | openssl s_client -starttls imap -showcerts -connect mx.mailcow.email:143
      -# Connect via HTTPS (443)
      -echo "Q" | openssl s_client -connect mx.mailcow.email:443
      -
      +

      ```

      +

      Connect via SMTP (587)

      +

      echo "Q" | openssl s_client -starttls smtp -crlf -connect mx.mailcow.email:587

      +

      Connect via IMAP (143)

      +

      echo "Q" | openssl s_client -starttls imap -showcerts -connect mx.mailcow.email:143

      +

      Connect via HTTPS (443)

      +

      echo "Q" | openssl s_client -connect mx.mailcow.email:443 +```

      To validate the expiry dates as returned by openssl against MAILCOW_HOSTNAME, you are able to use our helper script:

      -
      cd /opt/mailcow-dockerized
      -bash helper-scripts/expiry-dates.sh
      -
      +

      cd /opt/mailcow-dockerized +bash helper-scripts/expiry-dates.sh


      @@ -2829,7 +2892,7 @@ bash helper-scripts/expiry-dates.sh - + diff --git a/post_installation/firststeps-sync_jobs_migration/index.html b/post_installation/firststeps-sync_jobs_migration/index.html index 85f7eb185..6a51e6676 100644 --- a/post_installation/firststeps-sync_jobs_migration/index.html +++ b/post_installation/firststeps-sync_jobs_migration/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2574,7 +2574,7 @@ - + diff --git a/prerequisite/prerequisite-dns/index.html b/prerequisite/prerequisite-dns/index.html index 0ec51f516..ec2ee5510 100644 --- a/prerequisite/prerequisite-dns/index.html +++ b/prerequisite/prerequisite-dns/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -364,27 +364,75 @@
    • + + Name Type Value + + + +
    • + + Name Type Value + + +
    • + +
    • + + Name Type Value + + +
    • + +
    • + + Name Type Value + + + +
    • + + Name Type Priority Weight Port Value + + + + +
    • + + + + + + +
    • + + ``` + + +
    • + +
    • + + Summary of Results + + + + +
    • + +
    • + + ``` + + +
    • + +
    • + + Summary of Results + + +
    • @@ -2371,45 +2380,43 @@ -

      Gitea

      -

      With Gitea' ability to authenticate over SMTP it is trivial to integrate it with mailcow. Few changes are needed:

      1. Open docker-compose.override.yml and add gitea:

      -
      version: '2.1'
      -services:
      -
      -        gitea-mailcow:
      -            image: gitea/gitea:1
      -            volumes:
      -                - ./data/gitea:/data
      -            networks:
      -                mailcow-network:
      -                    aliases:
      -                        - gitea
      -            ports:
      -                - "${GITEA_SSH_PORT:-127.0.0.1:4000}:22"
      -
      +

      ``` +version: '2.1' +services:

      +
          gitea-mailcow:
      +        image: gitea/gitea:1
      +        volumes:
      +            - ./data/gitea:/data
      +        networks:
      +            mailcow-network:
      +                aliases:
      +                    - gitea
      +        ports:
      +            - "${GITEA_SSH_PORT:-127.0.0.1:4000}:22"
      +
      +

      ```

      2. Create data/conf/nginx/site.gitea.custom, add: -

      location /gitea/ {
      +location /gitea/ {
               proxy_pass http://gitea:3000/;
      -}
      -

      +}

      3. Open mailcow.conf and define the binding you want gitea to use for SSH. Example:

      -
      GITEA_SSH_PORT=127.0.0.1:4000
      -
      +

      GITEA_SSH_PORT=127.0.0.1:4000

      5. Run docker-compose up -d to bring up the gitea container and run docker-compose restart nginx-mailcow afterwards.

      6. If you forced mailcow to https, execute step 9 and restart gitea with docker-compose restart gitea-mailcow . Go head with step 7 (Remember to use https instead of http, https://mx.example.org/gitea/

      7. Open http://${MAILCOW_HOSTNAME}/gitea/, for example http://mx.example.org/gitea/. For database details set mysql as database host. Use the value of DBNAME found in mailcow.conf as database name, DBUSER as database user and DBPASS as database password.

      8. Once the installation is complete, login as admin and set "settings" -> "authorization" -> "enable SMTP". SMTP Host should be postfix with port 587, set Skip TLS Verify as we are using an unlisted SAN ("postfix" is most likely not part of your certificate).

      9. Create data/gitea/gitea/conf/app.ini and set following values. You can consult gitea cheat sheet for their meaning and other possible values.

      -
      [server]
      -SSH_LISTEN_PORT = 22
      -# For GITEA_SSH_PORT=127.0.0.1:4000 in mailcow.conf, set:
      -SSH_DOMAIN = 127.0.0.1
      -SSH_PORT = 4000
      -# For MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (and default ports for HTTPS), set:
      -ROOT_URL = https://mx.example.org/gitea/
      -
      +

      ``` +[server] +SSH_LISTEN_PORT = 22

      +

      For GITEA_SSH_PORT=127.0.0.1:4000 in mailcow.conf, set:

      +

      SSH_DOMAIN = 127.0.0.1 +SSH_PORT = 4000

      +

      For MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (and default ports for HTTPS), set:

      +

      ROOT_URL = https://mx.example.org/gitea/ +```

      10. Restart gitea with docker-compose restart gitea-mailcow. Your users should be able to login with mailcow managed accounts.


      @@ -2530,7 +2537,7 @@ ROOT_URL = https://mx.example.org/gitea/ - + diff --git a/third_party/third_party-gogs/index.html b/third_party/third_party-gogs/index.html index f8327d9b1..0e8b6b7eb 100644 --- a/third_party/third_party-gogs/index.html +++ b/third_party/third_party-gogs/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -66,6 +66,11 @@
      @@ -2251,6 +2256,8 @@ + + Gogs @@ -2354,6 +2361,8 @@ + +
      @@ -2371,44 +2380,42 @@ -

      Gogs

      -

      With Gogs' ability to authenticate over SMTP it is trivial to integrate it with mailcow. Few changes are needed:

      1. Open docker-compose.override.yml and add Gogs:

      -
      version: '2.1'
      -services:
      -
      -    gogs-mailcow:
      -      image: gogs/gogs
      -      volumes:
      -        - ./data/gogs:/data
      -      networks:
      -        mailcow-network:
      -          aliases:
      -            - gogs
      -      ports:
      -        - "${GOGS_SSH_PORT:-127.0.0.1:4000}:22"
      -
      +

      ``` +version: '2.1' +services:

      +
      gogs-mailcow:
      +  image: gogs/gogs
      +  volumes:
      +    - ./data/gogs:/data
      +  networks:
      +    mailcow-network:
      +      aliases:
      +        - gogs
      +  ports:
      +    - "${GOGS_SSH_PORT:-127.0.0.1:4000}:22"
      +
      +

      ```

      2. Create data/conf/nginx/site.gogs.custom, add: -

      location /gogs/ {
      +location /gogs/ {
           proxy_pass http://gogs:3000/;
      -}
      -

      +}

      3. Open mailcow.conf and define the binding you want Gogs to use for SSH. Example:

      -
      GOGS_SSH_PORT=127.0.0.1:4000
      -
      +

      GOGS_SSH_PORT=127.0.0.1:4000

      5. Run docker-compose up -d to bring up the Gogs container and run docker-compose restart nginx-mailcow afterwards.

      6. Open http://${MAILCOW_HOSTNAME}/gogs/, for example http://mx.example.org/gogs/. For database details set mysql as database host. Use the value of DBNAME found in mailcow.conf as database name, DBUSER as database user and DBPASS as database password.

      7. Once the installation is complete, login as admin and set "settings" -> "authorization" -> "enable SMTP". SMTP Host should be postfix with port 587, set Skip TLS Verify as we are using an unlisted SAN ("postfix" is most likely not part of your certificate).

      8. Create data/gogs/gogs/conf/app.ini and set following values. You can consult Gogs cheat sheet for their meaning and other possible values.

      -
      [server]
      -SSH_LISTEN_PORT = 22
      -# For GOGS_SSH_PORT=127.0.0.1:4000 in mailcow.conf, set:
      -SSH_DOMAIN = 127.0.0.1
      -SSH_PORT = 4000
      -# For MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (and default ports for HTTPS), set:
      -ROOT_URL = https://mx.example.org/gogs/
      -
      +

      ``` +[server] +SSH_LISTEN_PORT = 22

      +

      For GOGS_SSH_PORT=127.0.0.1:4000 in mailcow.conf, set:

      +

      SSH_DOMAIN = 127.0.0.1 +SSH_PORT = 4000

      +

      For MAILCOW_HOSTNAME=mx.example.org in mailcow.conf (and default ports for HTTPS), set:

      +

      ROOT_URL = https://mx.example.org/gogs/ +```

      9. Restart Gogs with docker-compose restart gogs-mailcow. Your users should be able to login with mailcow managed accounts.


      @@ -2529,7 +2536,7 @@ ROOT_URL = https://mx.example.org/gogs/ - + diff --git a/third_party/third_party-mailman3/index.html b/third_party/third_party-mailman3/index.html index d78c58d39..36ed7f657 100644 --- a/third_party/third_party-mailman3/index.html +++ b/third_party/third_party-mailman3/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2317,162 +2317,6 @@ DNS setup - - -
    • - - Install Apache as a reverse proxy - - - - -
    • - -
    • - - Obtain SSL certificates with Let's Encrypt - - -
    • - -
    • - - Install mailcow with Mailman integration - - - - -
    • - -
    • - - Install Mailman - - - - -
    • - -
    • - - 🏃 Run - - -
    • - - - - - - -
    • - - Remarks - - - - -
    • - -
    • - - Update - - -
    • - -
    • - - Backup - - -
    • - -
    • - - ToDo - - -
    • - -
    • - - Install Apache as a reverse proxy - - - - -
    • - -
    • - - Obtain SSL certificates with Let's Encrypt - - -
    • - -
    • - - Install mailcow with Mailman integration - - - - -
    • - -
    • - - Install Mailman - - - - -
    • - -
    • - - 🏃 Run - - -
    • - - - - - - -
    • - - Remarks - - - - -
    • - -
    • - - Update - - -
    • - -
    • - - Backup - - -
    • - -
    • - - ToDo - - -
    • The problem to solve

      mailpiler offers the authentication based on IMAP, for example:

      -
      $config['ENABLE_IMAP_AUTH'] = 1;
      -$config['IMAP_HOST'] = 'mail.example.com';
      -$config['IMAP_PORT'] =  993;
      -$config['IMAP_SSL'] = true;
      -
      +

      php +$config['ENABLE_IMAP_AUTH'] = 1; +$config['IMAP_HOST'] = 'mail.example.com'; +$config['IMAP_PORT'] = 993; +$config['IMAP_SSL'] = true;

      • So when you log in using patrik@example.com, you will only see delivered emails sent from or to this specific email address.
      • When additional aliases are defined in mailcow, like team@example.com, you won't see emails sent to or from this email address even the fact you're a recipient of mails sent to this alias address.
      • @@ -2515,19 +2515,19 @@
        1. Set the custom query function of mailpiler and append this to /usr/local/etc/piler/config-site.php:

          -
          $config['MAILCOW_API_KEY'] = 'YOUR_READONLY_API_KEY';
          -$config['MAILCOW_SET_REALNAME'] = true; // when not specified, then default is false
          -$config['CUSTOM_EMAIL_QUERY_FUNCTION'] = 'query_mailcow_for_email_access';
          -include('auth-mailcow.php');
          -
          +

          php +$config['MAILCOW_API_KEY'] = 'YOUR_READONLY_API_KEY'; +$config['MAILCOW_SET_REALNAME'] = true; // when not specified, then default is false +$config['CUSTOM_EMAIL_QUERY_FUNCTION'] = 'query_mailcow_for_email_access'; +include('auth-mailcow.php');

          You can also change the mailcow hostname, if required: -

          $config['MAILCOW_HOST'] = 'mail.domain.tld'; // defaults to $config['IMAP_HOST']
          -

          +php +$config['MAILCOW_HOST'] = 'mail.domain.tld'; // defaults to $config['IMAP_HOST']

        2. Download the PHP file with the functions from the GitHub repo:

          -
          curl -o /usr/local/etc/piler/auth-mailcow.php https://raw.githubusercontent.com/patschi/mailpiler-mailcow-integration/master/auth-mailcow.php
          -
          +

          sh +curl -o /usr/local/etc/piler/auth-mailcow.php https://raw.githubusercontent.com/patschi/mailpiler-mailcow-integration/master/auth-mailcow.php

        3. Done!

          @@ -2654,7 +2654,7 @@ - + diff --git a/third_party/third_party-nextcloud/index.html b/third_party/third_party-nextcloud/index.html index 6211ab568..a813e6a89 100644 --- a/third_party/third_party-nextcloud/index.html +++ b/third_party/third_party-nextcloud/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2485,14 +2485,13 @@

          In order for mailcow to generate a a certificate for the nextcloud domain you need to add "nextcloud.domain.tld" to ADDITIONAL_SAN in mailcow.conf and run docker-compose up -d to apply. For more informaton refer to: Advanced SSL.

          Background jobs

          To use the recommended setting (cron) to execute the background jobs following lines need to be added to the docker-compose.override.yml:

          -
          version: '2.1'
          +

          version: '2.1' services: php-fpm-mailcow: labels: - ofelia.enabled: "true" - ofelia.job-exec.nextcloud-cron.schedule: "@every 5m" - ofelia.job-exec.nextcloud-cron.command: "su www-data -s /bin/bash -c \"/usr/local/bin/php -f /web/nextcloud/cron.php\"" -

          + ofelia.enabled: "true" + ofelia.job-exec.nextcloud-cron.schedule: "@every 5m" + ofelia.job-exec.nextcloud-cron.command: "su www-data -s /bin/bash -c \"/usr/local/bin/php -f /web/nextcloud/cron.php\""

          After adding these lines the docker-compose up -d command must be executed to update the docker image and also the docker scheduler image must be restarted to pick up the new job definition by executing docker-compose restart ofelia-mailcow. To check if the job was successfully picked up by ofelia the command docker-compose logs ofelia-mailcow will contain a line similar to New job registered "nextcloud-cron" - ....

          @@ -2544,14 +2543,12 @@ services:

          If you have previously used Nextcloud with mailcow authentication via user_external/IMAP, you need to perform some additional steps to link your existing user accounts with OAuth2.

          1. Click the button in the top right corner and select Apps. Scroll down to the External user authentication app and click Remove next to it. 2. Run the following queries in your Nextcloud database (if you set up Nextcloud using mailcow's script, you can run source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME): -

          INSERT INTO nc_users (uid, uid_lower) SELECT DISTINCT uid, LOWER(uid) FROM nc_users_external;
          -INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users_external;
          -

          +INSERT INTO nc_users (uid, uid_lower) SELECT DISTINCT uid, LOWER(uid) FROM nc_users_external; +INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users_external;


          If you have previously used Nextcloud without mailcow authentication, but with the same usernames as mailcow, you can also link your existing user accounts with OAuth2.

          1. Run the following queries in your Nextcloud database (if you set up Nextcloud using mailcow's script, you can run source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME): -

          INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users;
          -

          +INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users;


          Update

          The Nextcloud instance can be updated easily with the web update mechanism. In the case of larger updates, there may be further changes to be made after the update. After the Nextcloud instance has been checked, problems are shown. This can be e.g. missing indices in the DB or similar. @@ -2561,13 +2558,12 @@ It shows which commands have to be executed, these have to be placed in the php-


          Debugging & Troubleshooting

          It may happen that you cannot reach the Nextcloud instance from your network. This may be due to the fact that the entry of your subnet in the array 'trusted_proxies' is missing. You can make changes in the Nextcloud config.php in data/web/nextcloud/config/*.

          -
          'trusted_proxies' =>
          +

          'trusted_proxies' => array ( - 0 => 'fd4d:6169:6c63:6f77::/64', - 1 => '172.22.1.0/24', - 2 => 'NewSubnet/24', - ), -

          + 0 => 'fd4d:6169:6c63:6f77::/64', + 1 => '172.22.1.0/24', + 2 => 'NewSubnet/24', + ),

          After the changes have been made, the nginx container must be restarted. docker-compose restart nginx-mailcow

          @@ -2689,7 +2685,7 @@ It shows which commands have to be executed, these have to be placed in the php- - + diff --git a/third_party/third_party-portainer/index.html b/third_party/third_party-portainer/index.html index cb6dc024b..0a8174506 100644 --- a/third_party/third_party-portainer/index.html +++ b/third_party/third_party-portainer/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2375,7 +2375,7 @@

          In order to enable Portainer, the docker-compose.yml and site.conf for Nginx must be modified.

          1. Create a new file docker-compose.override.yml in the mailcow-dockerized root folder and insert the following configuration -

          version: '2.1'
          +version: '2.1'
           services:
               portainer-mailcow:
                 image: portainer/portainer-ce
          @@ -2389,42 +2389,40 @@ services:
                 networks:
                   mailcow-network:
                     aliases:
          -            - portainer
          -
          + - portainer 2a. Create data/conf/nginx/portainer.conf: -
          upstream portainer {
          +```
          +upstream portainer {
             server portainer-mailcow:9000;
          -}
          -
          -map $http_upgrade $connection_upgrade {
          +}

          +

          map $http_upgrade $connection_upgrade { default upgrade; - '' close; + '' close; } -

          +```

          2b. Insert a new location to the default mailcow site by creating the file data/conf/nginx/site.portainer.custom: -

            location /portainer/ {
          +```
          +  location /portainer/ {
               proxy_http_version 1.1;
          -    proxy_set_header Host              $http_host;   # required for docker client's sake
          -    proxy_set_header X-Real-IP         $remote_addr; # pass on real client's IP
          +    proxy_set_header Host              $http_host;   # required for docker client's sake
          +    proxy_set_header X-Real-IP         $remote_addr; # pass on real client's IP
               proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
               proxy_set_header X-Forwarded-Proto $scheme;
          -    proxy_read_timeout                 900;
          -
          -    proxy_set_header Connection "";
          -    proxy_buffers 32 4k;
          -    proxy_pass http://portainer/;
          -  }
          -
          -  location /portainer/api/websocket/ {
          +    proxy_read_timeout                 900;

          +
          proxy_set_header Connection "";
          +proxy_buffers 32 4k;
          +proxy_pass http://portainer/;
          +
          +

          }

          +

          location /portainer/api/websocket/ { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; - proxy_pass http://portainer/api/websocket/; + proxy_pass http://portainer/api/websocket/; } -

          +```

          3. Apply your changes: -

          docker-compose up -d && docker-compose restart nginx-mailcow
          -

          +docker-compose up -d && docker-compose restart nginx-mailcow

          Now you can simply navigate to https://${MAILCOW_HOSTNAME}/portainer/ to view your Portainer container monitoring page. You’ll then be prompted to specify a new password for the admin account. After specifying your password, you’ll then be able to connect to the Portainer UI.


          @@ -2545,7 +2543,7 @@ map $http_upgrade $connection_upgrade { - + diff --git a/third_party/third_party-roundcube/index.html b/third_party/third_party-roundcube/index.html index f28fe108c..08e6d4662 100644 --- a/third_party/third_party-roundcube/index.html +++ b/third_party/third_party-roundcube/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2357,38 +2357,134 @@
        4. + + Check for a newer release! + + +
        5. + +
        6. + + Change folder name + + +
        7. + +
        8. + + Change permissions + + +
        9. + +
        10. + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 + + +
        11. + +
        12. + + !/bin/bash + + + +
        13. + + Enter a bash session of the mailcow PHP container + + +
        14. + +
        15. + + Install required upgrade dependency, then upgrade Roundcube to wanted release + + +
        16. + +
        17. + + Type 'Y' and press enter to upgrade your install of Roundcube + + +
        18. + +
        19. + + Remove leftover files + + +
        20. + +
        21. + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 + + + + +
        22. + +
        23. + + Allow admins to log into Roundcube as email user (without any password) + + +
        24. + +
        25. + + Roundcube with plugin dovecot_impersonate must be installed first + +
      @@ -2438,38 +2534,134 @@
    • + + Check for a newer release! + + +
    • + +
    • + + Change folder name + + +
    • + +
    • + + Change permissions + + +
    • + +
    • + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 + + +
    • + +
    • + + !/bin/bash + + + +
    • + + Enter a bash session of the mailcow PHP container + + +
    • + +
    • + + Install required upgrade dependency, then upgrade Roundcube to wanted release + + +
    • + +
    • + + Type 'Y' and press enter to upgrade your install of Roundcube + + +
    • + +
    • + + Remove leftover files + + +
    • + +
    • + + Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 + + + + +
    • + +
    • + + Allow admins to log into Roundcube as email user (without any password) + + +
    • + +
    • + + Roundcube with plugin dovecot_impersonate must be installed first + +
    • @@ -2490,124 +2682,114 @@ -

      Roundcube

      -

      Installing Roundcube

      Download Roundcube 1.5.x to the web htdocs directory and extract it (here rc/): -

      # Check for a newer release!
      -cd data/web
      -wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz -
      -
      -# Change folder name
      -mv roundcubemail-1.5.2 rc
      -
      -# Change permissions
      -chown -R root: rc/
      -
      -# Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6
      -sed -i "s/\$prefix = '\.\/';/\$prefix = preg_replace\('\/\[\?\&]\.\*\$\/', '', \$_SERVER\['REQUEST_URI'] \?\? ''\) \?: '\.\/';/g" rc/program/include/rcmail.php
      -

      +```

      +

      Check for a newer release!

      +

      cd data/web +wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz -

      +

      Change folder name

      +

      mv roundcubemail-1.5.2 rc

      +

      Change permissions

      +

      chown -R root: rc/

      +

      Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6

      +

      sed -i "s/\$prefix = '.\/';/\$prefix = preg_replace('\/[\?\&].*\$\/', '', \$_SERVER['REQUEST_URI'] \?\? '') \?: '.\/';/g" rc/program/include/rcmail.php +```

      If you need spell check features, create a file data/hooks/phpfpm/aspell.sh with the following content, then chmod +x data/hooks/phpfpm/aspell.sh. This installs a local spell check engine. Note, most modern web browsers have built in spell check, so you may not want/need this. -

      #!/bin/bash
      -apk update
      +```

      +

      !/bin/bash

      +

      apk update apk add aspell-en # or any other language -

      +```

      Create a file data/web/rc/config/config.inc.php with the following content. - Change the des_key parameter to a random value. It is used to temporarily store your IMAP password. - The db_prefix is optional but recommended. - If you didn't install spell check in the above step, remove spellcheck_engine parameter and replace it with $config['enable_spellcheck'] = false;. -

      <?php
      +<?php
       error_reporting(0);
      -if (!file_exists('/tmp/mime.types')) {
      -file_put_contents("/tmp/mime.types", fopen("http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types", 'r'));
      +if (!file_exists('/tmp/mime.types')) {
      +file_put_contents("/tmp/mime.types", fopen("http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types", 'r'));
       }
       $config = array();
      -$config['db_dsnw'] = 'mysql://' . getenv('DBUSER') . ':' . getenv('DBPASS') . '@mysql/' . getenv('DBNAME');
      -$config['default_host'] = 'tls://dovecot';
      -$config['default_port'] = '143';
      -$config['smtp_server'] = 'tls://postfix';
      -$config['smtp_port'] = 587;
      -$config['smtp_user'] = '%u';
      -$config['smtp_pass'] = '%p';
      -$config['support_url'] = '';
      -$config['product_name'] = 'Roundcube Webmail';
      -$config['des_key'] = 'yourrandomstring_changeme';
      -$config['log_dir'] = '/dev/null';
      -$config['temp_dir'] = '/tmp';
      -$config['plugins'] = array(
      -  'archive',
      -  'managesieve'
      +$config['db_dsnw'] = 'mysql://' . getenv('DBUSER') . ':' . getenv('DBPASS') . '@mysql/' . getenv('DBNAME');
      +$config['default_host'] = 'tls://dovecot';
      +$config['default_port'] = '143';
      +$config['smtp_server'] = 'tls://postfix';
      +$config['smtp_port'] = 587;
      +$config['smtp_user'] = '%u';
      +$config['smtp_pass'] = '%p';
      +$config['support_url'] = '';
      +$config['product_name'] = 'Roundcube Webmail';
      +$config['des_key'] = 'yourrandomstring_changeme';
      +$config['log_dir'] = '/dev/null';
      +$config['temp_dir'] = '/tmp';
      +$config['plugins'] = array(
      +  'archive',
      +  'managesieve'
       );
      -$config['spellcheck_engine'] = 'aspell';
      -$config['mime_types'] = '/tmp/mime.types';
      -$config['imap_conn_options'] = array(
      -  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
      +$config['spellcheck_engine'] = 'aspell';
      +$config['mime_types'] = '/tmp/mime.types';
      +$config['imap_conn_options'] = array(
      +  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
       );
      -$config['enable_installer'] = true;
      -$config['smtp_conn_options'] = array(
      -  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
      +$config['enable_installer'] = true;
      +$config['smtp_conn_options'] = array(
      +  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
       );
      -$config['db_prefix'] = 'mailcow_rc1';
      -

      +$config['db_prefix'] = 'mailcow_rc1';

      Point your browser to https://myserver/rc/installer and follow the instructions. Initialize the database and leave the installer.

      Delete the directory data/web/rc/installer after a successful installation!

      Configure ManageSieve filtering

      Open data/web/rc/plugins/managesieve/config.inc.php and change the following parameters (or add them at the bottom of that file): -

      $config['managesieve_port'] = 4190;
      -$config['managesieve_host'] = 'tls://dovecot';
      -$config['managesieve_conn_options'] = array(
      -  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
      +$config['managesieve_port'] = 4190;
      +$config['managesieve_host'] = 'tls://dovecot';
      +$config['managesieve_conn_options'] = array(
      +  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true)
       );
       // Enables separate management interface for vacation responses (out-of-office)
       // 0 - no separate section (default),
       // 1 - add Vacation section,
       // 2 - add Vacation section, but hide Filters section
      -$config['managesieve_vacation'] = 1;
      -

      +$config['managesieve_vacation'] = 1;

      Enable change password function in Roundcube

      Open data/web/rc/config/config.inc.php and enable the password plugin:

      -
      ...
      -$config['plugins'] = array(
      -    'archive',
      -    'password',
      +

      ... +$config['plugins'] = array( + 'archive', + 'password', ); -... -

      +...

      Open data/web/rc/plugins/password/password.php, search for case 'ssha': and add above:

      -
              case 'ssha256':
      +

      case 'ssha256': $salt = rcube_utils::random_bytes(8); - $crypted = base64_encode( hash('sha256', $password . $salt, TRUE ) . $salt ); - $prefix = '{SSHA256}'; - break; -

      + $crypted = base64_encode( hash('sha256', $password . $salt, TRUE ) . $salt ); + $prefix = '{SSHA256}'; + break;

      Open data/web/rc/plugins/password/config.inc.php and change the following parameters (or add them at the bottom of that file):

      -
      $config['password_driver'] = 'sql';
      -$config['password_algorithm'] = 'ssha256';
      -$config['password_algorithm_prefix'] = '{SSHA256}';
      -$config['password_query'] = "UPDATE mailbox SET password = %P WHERE username = %u";
      -
      +

      $config['password_driver'] = 'sql'; +$config['password_algorithm'] = 'ssha256'; +$config['password_algorithm_prefix'] = '{SSHA256}'; +$config['password_query'] = "UPDATE mailbox SET password = %P WHERE username = %u";

      Integrate CardDAV addressbooks in Roundcube

      Download the latest release of RCMCardDAV to the Roundcube plugin directory and extract it (here rc/plugins): -

      cd data/web/rc/plugins
      +cd data/web/rc/plugins
       wget -O - https://github.com/mstilkerich/rcmcarddav/releases/download/v4.3.0/carddav-v4.3.0.tar.gz  | tar xfvz -
      -chown -R root: carddav/
      -

      +chown -R root: carddav/

      Copy the file config.inc.php.dist to config.inc.php (here in rc/plugins/carddav) and append the following preset to the end of the file - don't forget to replace mx.example.org with your own hostname: -

      $prefs['SOGo'] = array(
      -    'name'         =>  'SOGo',
      -    'username'     =>  '%u',
      -    'password'     =>  '%p',
      -    'url'          =>  'https://mx.example.org/SOGo/dav/%u/',
      -    'carddav_name_only' => true,
      -    'use_categories' => true,
      -    'active'       =>  true,
      -    'readonly'     =>  false,
      -    'refresh_time' => '02:00:00',
      -    'fixed'        =>  array( 'active', 'name', 'username', 'password', 'refresh_time' ),
      -    'hide'        =>  false,
      -);
      -
      +$prefs['SOGo'] = array( + 'name' => 'SOGo', + 'username' => '%u', + 'password' => '%p', + 'url' => 'https://mx.example.org/SOGo/dav/%u/', + 'carddav_name_only' => true, + 'use_categories' => true, + 'active' => true, + 'readonly' => false, + 'refresh_time' => '02:00:00', + 'fixed' => array( 'active', 'name', 'username', 'password', 'refresh_time' ), + 'hide' => false, +); Please note, that this preset only integrates the default addressbook (the one that's named "Personal Address Book" and can't be deleted). Additional addressbooks are currently not automatically detected but can be manually added within the roundecube settings.

      Enable the plugin by adding carddav to $config['plugins'] in rc/config/config.inc.php.

      If you want to remove the default addressbooks (stored in the Roundcube database), so that only the CardDAV addressbooks are accessible, append $config['address_book_type'] = ''; to the config file data/web/rc/config/config.inc.php.

      @@ -2615,75 +2797,70 @@ Please note, that this preset only integrates the default addressbook (the one t

      Optionally, you can add Roundcube's link to the mailcow Apps list. To do this, open or create data/web/inc/vars.local.inc.php and add the following code-block:

      NOTE: Don't forget to add the <?php delimiter on the first line

      -
      ...
      +

      ... $MAILCOW_APPS = array( array( - 'name' => 'SOGo', - 'link' => '/SOGo/' + 'name' => 'SOGo', + 'link' => '/SOGo/' ), array( - 'name' => 'Roundcube', - 'link' => '/rc/' + 'name' => 'Roundcube', + 'link' => '/rc/' ) ); -... -

      +...

      Upgrading Roundcube

      Upgrading Roundcube is rather simple, go to the Github releases page for Roundcube and get the link for the "complete.tar.gz" file for the wanted release. Then follow the below commands and change the URL and Roundcube folder name if needed.

      -
      # Enter a bash session of the mailcow PHP container
      -docker exec -it mailcowdockerized_php-fpm-mailcow_1 bash
      -
      -# Install required upgrade dependency, then upgrade Roundcube to wanted release
      -apk add rsync
      +

      ```

      +

      Enter a bash session of the mailcow PHP container

      +

      docker exec -it mailcowdockerized_php-fpm-mailcow_1 bash

      +

      Install required upgrade dependency, then upgrade Roundcube to wanted release

      +

      apk add rsync cd /tmp -wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz - +wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5.2/roundcubemail-1.5.2-complete.tar.gz | tar xfvz - cd roundcubemail-1.5.2 -bin/installto.sh /web/rc - -# Type 'Y' and press enter to upgrade your install of Roundcube - -# Remove leftover files -cd /tmp -rm -rf roundcube* - -# Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6 -sed -i "s/\$prefix = '\.\/';/\$prefix = preg_replace\('\/\[\?\&]\.\*\$\/', '', \$_SERVER\['REQUEST_URI'] \?\? ''\) \?: '\.\/';/g" /web/rc/program/include/rcmail.php -

      +bin/installto.sh /web/rc

      +

      Type 'Y' and press enter to upgrade your install of Roundcube

      +

      Remove leftover files

      +

      cd /tmp +rm -rf roundcube*

      +

      Fix Allow remote resources (https://github.com/roundcube/roundcubemail/issues/8170) should not be required in 1.6

      +

      sed -i "s/\$prefix = '.\/';/\$prefix = preg_replace('\/[\?\&].*\$\/', '', \$_SERVER['REQUEST_URI'] \?\? '') \?: '.\/';/g" /web/rc/program/include/rcmail.php +```

      Let admins log into Roundcube without password

      First, install plugin dovecot_impersonate and add Roundcube as an app (see above).

      Edit mailcow.conf and add the following:

      -
      # Allow admins to log into Roundcube as email user (without any password)
      -# Roundcube with plugin dovecot_impersonate must be installed first
      -
      -ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=y
      -
      +

      ```

      +

      Allow admins to log into Roundcube as email user (without any password)

      +

      Roundcube with plugin dovecot_impersonate must be installed first

      +

      ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=y +```

      Edit docker-compose.override.yml and crate/extend the section for php-fpm-mailcow:

      -
      version: '2.1'
      +

      yml +version: '2.1' services: php-fpm-mailcow: environment: - - ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=${ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE:-n} -

      + - ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE=${ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE:-n}

      Edit data/web/js/site/mailbox.js and the following code after if (ALLOW_ADMIN_EMAIL_LOGIN) { ... }

      -
      if (ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE) {
      -  item.action += '<a href="/rc-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs ' + btnSize + ' btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> Roundcube</a>';
      -}
      -
      +

      js +if (ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE) { + item.action += '<a href="/rc-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs ' + btnSize + ' btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> Roundcube</a>'; +}

      Edit data/web/mailbox.php and add this line to array $template_data:

      -
        'allow_admin_email_login_roundcube' => (preg_match("/^(yes|y)+$/i", $_ENV["ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE"])) ? 'true' : 'false',
      -
      +

      php + 'allow_admin_email_login_roundcube' => (preg_match("/^(yes|y)+$/i", $_ENV["ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE"])) ? 'true' : 'false',

      Edit data/web/templates/mailbox.twig and add this code to the bottom of the javascript section:

      -
        var ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE = {{ allow_admin_email_login_roundcube }};
      -
      +

      js + var ALLOW_ADMIN_EMAIL_LOGIN_ROUNDCUBE = {{ allow_admin_email_login_roundcube }};

      Copy the contents of the following files from this Snippet:

      • data/web/inc/lib/RoundcubeAutoLogin.php
      • data/web/rc-auth.php

      Finally, restart mailcow

      -
      docker-compose down
      -docker-compose up -d
      -
      +

      docker-compose down +docker-compose up -d


      @@ -2788,7 +2965,7 @@ docker-compose up -d - + diff --git a/troubleshooting/debug-admin_login_sogo/index.html b/troubleshooting/debug-admin_login_sogo/index.html index c8b0590f5..ce969f846 100644 --- a/troubleshooting/debug-admin_login_sogo/index.html +++ b/troubleshooting/debug-admin_login_sogo/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2456,11 +2456,9 @@ log into SOGo as a mailbox user, without knowing the users password.

      Multiple concurrent admin-logins to different mailboxes are also possible when using this feature.

      Enabling the feature

      The feature is disabled by default. It can be enabled in the mailcow.conf by setting: -

      ALLOW_ADMIN_EMAIL_LOGIN=y
      -
      +ALLOW_ADMIN_EMAIL_LOGIN=y and recreating the affected containers with -
      docker-compose up -d
      -

      +docker-compose up -d

      Drawbacks when enabled

      • Each SOGo page-load and each Active-Sync request will cause an additional execution of an internal PHP script. @@ -2606,7 +2604,7 @@ In most cases, this should not be noticeable but should be kept in mind if you f - + diff --git a/troubleshooting/debug-attach_service/index.html b/troubleshooting/debug-attach_service/index.html index 45c6f5bb7..64168dc87 100644 --- a/troubleshooting/debug-attach_service/index.html +++ b/troubleshooting/debug-attach_service/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2504,17 +2504,14 @@

        Attaching a Container to your Shell

        To attach a container to your shell you can simply run

        -
        docker-compose exec $Service_Name /bin/bash
        -
        +

        docker-compose exec $Service_Name /bin/bash

        Connecting to Services

        If you want to connect to a service / application directly it is always a good idea to source mailcow.conf to get all relevant variables into your environment.

        MySQL

        -
        source mailcow.conf
        -docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
        -
        +

        source mailcow.conf +docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}

        Redis

        -
        docker-compose exec redis-mailcow redis-cli
        -
        +

        docker-compose exec redis-mailcow redis-cli

        Service Descriptions

        Here is a brief overview of what container / service does what:

      @@ -2710,7 +2707,7 @@ docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} - + diff --git a/troubleshooting/debug-common_problems/index.html b/troubleshooting/debug-common_problems/index.html index ea27d1288..0c364a38e 100644 --- a/troubleshooting/debug-common_problems/index.html +++ b/troubleshooting/debug-common_problems/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -801,52 +801,65 @@
    • + + telnet 74.125.133.27 465 + + + +
    • @@ -2466,52 +2479,65 @@
    • + + telnet 74.125.133.27 465 + + + +
    • @@ -2532,8 +2558,6 @@ -

      Common Problems

      -

      Here we list common problems and possible solutions:

      Mail loops back to myself

      Please check in your mailcow UI if you made the domain a backup MX:

      @@ -2544,11 +2568,12 @@
    • Check if your IP address is on any blacklists. You could use dnsbl.info or any other similar service to check for your IP address.
    • There are some consumer ISP routers out there, that block mail ports for non whitelisted domains. Please check if you can reach your server on the ports 465 or 587:
    • -
      # telnet 74.125.133.27 465
      -Trying 74.125.133.27...
      +

      ```

      +

      telnet 74.125.133.27 465

      +

      Trying 74.125.133.27... Connected to 74.125.133.27. -Escape character is '^]'. -

      +Escape character is '^]'. +```

      My mails are identified as Spam

      Please read our guide on DNS configuration.

      docker-compose throws weird errors

      @@ -2565,8 +2590,7 @@ Escape character is '^]'.

      It might also be wrongly linked file (i.e. SSL certificate) that prevents a crucial container (nginx) from starting, so always check your logs to get an idea where your problem is coming from.

      Address already in use

      If you get an error message like:

      -
      ERROR: for postfix-mailcow  Cannot start service postfix-mailcow: driver failed programming external     connectivity on endpoint mailcowdockerized_postfix-mailcow_1: Error starting userland proxy: listen tcp 0.0.0.0:25: bind: address already in use
      -
      +

      ERROR: for postfix-mailcow Cannot start service postfix-mailcow: driver failed programming external connectivity on endpoint mailcowdockerized_postfix-mailcow_1: Error starting userland proxy: listen tcp 0.0.0.0:25: bind: address already in use

      while trying to start / install mailcow: dockerized, make sure you've followed our section on the prerequisites.

      XYZ can't connect to ...

      Please check your local firewall! @@ -2574,19 +2598,17 @@ Docker and iptables-based firewalls sometimes create conflicting rules, so disab

      If you experience connection problems from home, please check your ISP router's firewall too, some of them block mail traffic on the SMTP (587) or SMTPS (465) ports. It could also be, that your ISP is blocking the ports for SUBMISSION (25).

      While Linux users can chose from a variety of tools1 to check if a port is open, the Windows user has only the PowerShell command Test-NetConnection -ComputerName host -Port port available by default.

      To enable telnet on a Windows after Vista please check this guide or enter the following command in an terminal with administrator privileges:

      -
      dism /online /Enable-Feature /FeatureName:TelnetClient
      -
      +

      dism /online /Enable-Feature /FeatureName:TelnetClient

      Inotify instance limit for user 5000 (UID vmail) exceeded (see #453)

      Docker containers use the Docker hosts inotify limits. Setting them on your Docker host will pass them to the container.

      Dovecot keeps restarting (see #2672)

      Check that you have at least the following files in data/assets/ssl:

      -
      cert.pem
      +

      cert.pem dhparams.pem -key.pem -

      +key.pem

      If dhparams.pem is missing, you can generate it with

      -
      openssl dhparam -out data/assets/ssl/dhparams.pem 4096
      -
      +

      bash +openssl dhparam -out data/assets/ssl/dhparams.pem 4096


        @@ -2714,7 +2736,7 @@ key.pem - + diff --git a/troubleshooting/debug-logs/index.html b/troubleshooting/debug-logs/index.html index ff9e9b514..260baebc4 100644 --- a/troubleshooting/debug-logs/index.html +++ b/troubleshooting/debug-logs/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2508,7 +2508,7 @@ - + diff --git a/troubleshooting/debug-mysql_aria/index.html b/troubleshooting/debug-mysql_aria/index.html index 31e4faf6b..bac65c9f2 100644 --- a/troubleshooting/debug-mysql_aria/index.html +++ b/troubleshooting/debug-mysql_aria/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -833,6 +833,41 @@ MariaDB: Aria recovery after crash + + +
      1. + + Stop the stack, don't run "down" + + +
      2. + +
      3. + + Run a bash in the stopped container as user mysql + + +
      4. + +
      5. + + cd to the SQL data directory + + +
      6. + +
      7. + + Run aria_chk + + +
      8. + +
      9. + + Delete aria log files + +
      10. @@ -2400,6 +2435,41 @@ MariaDB: Aria recovery after crash + + +
      11. + + Stop the stack, don't run "down" + + +
      12. + +
      13. + + Run a bash in the stopped container as user mysql + + +
      14. + +
      15. + + cd to the SQL data directory + + +
      16. + +
      17. + + Run aria_chk + + +
      18. + +
      19. + + Delete aria log files + +
      20. @@ -2420,23 +2490,22 @@ -

        Recover crashed Aria storage engine

        -

        MariaDB: Aria recovery after crash

        If your server crashed and MariaDB logs an error similar to [ERROR] mysqld: Aria recovery failed. Please run aria_chk -r on all Aria tables (*.MAI) and delete all aria_log.######## files you may want to try the following to recover the database to a healthy state:

        Start the stack and wait until mysql-mailcow begins to report a restarting state. Check by running docker-compose ps.

        Now run the following commands:

        -
        # Stop the stack, don't run "down"
        -docker-compose stop
        -# Run a bash in the stopped container as user mysql
        -docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql bash"' mysql-mailcow
        -# cd to the SQL data directory
        -cd /var/lib/mysql
        -# Run aria_chk
        -aria_chk --check --force */*.MAI
        -# Delete aria log files
        -rm aria_log.*
        -
        +

        ```

        +

        Stop the stack, don't run "down"

        +

        docker-compose stop

        +

        Run a bash in the stopped container as user mysql

        +

        docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql bash"' mysql-mailcow

        +

        cd to the SQL data directory

        +

        cd /var/lib/mysql

        +

        Run aria_chk

        +

        aria_chk --check --force /.MAI

        +

        Delete aria log files

        +

        rm aria_log.* +```

        Now run docker-compose down followed by docker-compose up -d.


        @@ -2557,7 +2626,7 @@ rm aria_log.* - + diff --git a/troubleshooting/debug-mysql_upgrade/index.html b/troubleshooting/debug-mysql_upgrade/index.html index 67e9425b1..b70da0678 100644 --- a/troubleshooting/debug-mysql_upgrade/index.html +++ b/troubleshooting/debug-mysql_upgrade/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2424,13 +2424,11 @@

        Run a manual mysql_upgrade

        This step is usually not necessary.

        -
        docker-compose stop mysql-mailcow watchdog-mailcow
        -docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && bash && exit 0"' mysql-mailcow
        -
        +

        docker-compose stop mysql-mailcow watchdog-mailcow +docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && bash && exit 0"' mysql-mailcow

        As soon as the SQL shell spawned, run mysql_upgrade and exit the container:

        -
        mysql_upgrade
        -exit
        -
        +

        mysql_upgrade +exit


        @@ -2550,7 +2548,7 @@ exit - + diff --git a/troubleshooting/debug-reset_pw/index.html b/troubleshooting/debug-reset_pw/index.html index 25cecfa85..c81b32553 100644 --- a/troubleshooting/debug-reset_pw/index.html +++ b/troubleshooting/debug-reset_pw/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -878,6 +878,26 @@ + + + + + +
      21. + + source mailcow.conf + + +
      22. + +
      23. + + docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} + + + - -
      24. - -
      25. +
      26. Remove Two-Factor Authentication @@ -935,6 +950,11 @@ +
      27. + + + + @@ -2491,6 +2511,26 @@ + + + + + +
      28. + + source mailcow.conf + + +
      29. + +
      30. + + docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} + + + - -
      31. - -
      32. +
      33. Remove Two-Factor Authentication @@ -2548,6 +2583,11 @@ +
      34. + + + + @@ -2568,22 +2608,19 @@ -

        Reset Passwords (incl. SQL)

        -

        mailcow Admin Account

        Resets the mailcow admin account to a random password. Older mailcow: dockerized installations may find the mailcow-reset-admin.sh script in their mailcow root directory (mailcow_path).

        -
        cd mailcow_path
        -./helper-scripts/mailcow-reset-admin.sh
        -
        +

        cd mailcow_path +./helper-scripts/mailcow-reset-admin.sh

        Reset MySQL Passwords

        Stop the stack by running docker-compose stop.

        When the containers came to a stop, run this command:

        -
        docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && mysql -hlocalhost -uroot && exit 0"' mysql-mailcow
        -
        +

        docker-compose run --rm --entrypoint '/bin/sh -c "gosu mysql mysqld --skip-grant-tables & sleep 10 && mysql -hlocalhost -uroot && exit 0"' mysql-mailcow

        1. Find database name

        -
        # source mailcow.conf
        -# docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}
        -MariaDB [(none)]> show databases;
        +

        ```

        +

        source mailcow.conf

        +

        docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME}

        +

        MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ @@ -2593,49 +2630,47 @@ MariaDB [(none)]> show databases; | performance_schema | +--------------------+ 4 rows in set (0.00 sec) -

        +```

        2. Reset one or more users

        2.1 Maria DB < 10.4 (older mailcow installations)

        Both "password" and "authentication_string" exist. Currently "password" is used, but better set both.

        -
        MariaDB [(none)]> SELECT user FROM mysql.user;
        +

        ``` +MariaDB [(none)]> SELECT user FROM mysql.user; +--------------+ | user | +--------------+ | mailcow | <===== | root | +--------------+ -2 rows in set (0.00 sec) - +2 rows in set (0.00 sec)

        +

        MariaDB [(none)]> FLUSH PRIVILEGES; +MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('gotr00t'), password = PASSWORD('gotr00t') WHERE User = 'root'; +MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('mookuh'), password = PASSWORD('mookuh') WHERE User = 'mailcow' AND Host = '%'; MariaDB [(none)]> FLUSH PRIVILEGES; -MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('gotr00t'), password = PASSWORD('gotr00t') WHERE User = 'root'; -MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('mookuh'), password = PASSWORD('mookuh') WHERE User = 'mailcow' AND Host = '%'; -MariaDB [(none)]> FLUSH PRIVILEGES; -

        +```

        2.2 Maria DB >= 10.4 (current mailcows)

        -
        MariaDB [(none)]> SELECT user FROM mysql.user;
        +

        ``` +MariaDB [(none)]> SELECT user FROM mysql.user; +--------------+ | user | +--------------+ | mailcow | <===== | root | +--------------+ -2 rows in set (0.00 sec) - +2 rows in set (0.00 sec)

        +

        MariaDB [(none)]> FLUSH PRIVILEGES; +MariaDB [(none)]> ALTER USER 'mailcow'@'%' IDENTIFIED BY 'mookuh'; +MariaDB [(none)]> ALTER USER 'root'@'%' IDENTIFIED BY 'gotr00t'; +MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'gotr00t'; MariaDB [(none)]> FLUSH PRIVILEGES; -MariaDB [(none)]> ALTER USER 'mailcow'@'%' IDENTIFIED BY 'mookuh'; -MariaDB [(none)]> ALTER USER 'root'@'%' IDENTIFIED BY 'gotr00t'; -MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'gotr00t'; -MariaDB [(none)]> FLUSH PRIVILEGES; -

        +```

        Remove Two-Factor Authentication

        For mailcow WebUI:

        This works similar to resetting a MySQL password, now we do it from the host without connecting to the MySQL CLI:

        -
        source mailcow.conf
        -docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='YOUR_USERNAME';"
        -
        +

        source mailcow.conf +docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='YOUR_USERNAME';"

        For SOGo:

        -
        docker-compose exec -u sogo sogo-mailcow sogo-tool user-preferences set defaults user@example.com SOGoGoogleAuthenticatorEnabled '{"SOGoGoogleAuthenticatorEnabled":0}'
        -
        +

        docker-compose exec -u sogo sogo-mailcow sogo-tool user-preferences set defaults user@example.com SOGoGoogleAuthenticatorEnabled '{"SOGoGoogleAuthenticatorEnabled":0}'


        @@ -2755,7 +2790,7 @@ docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e &qu - + diff --git a/troubleshooting/debug-reset_tls/index.html b/troubleshooting/debug-reset_tls/index.html index 75b70ed55..7d1cabcca 100644 --- a/troubleshooting/debug-reset_tls/index.html +++ b/troubleshooting/debug-reset_tls/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2374,14 +2374,13 @@

        Reset TLS certificates

        In case you encounter problems with your certificate, key or Let's Encrypt account, please try to reset the TLS assets:

        -
        source mailcow.conf
        +

        source mailcow.conf docker-compose down rm -rf data/assets/ssl mkdir data/assets/ssl -openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes +openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes cp -n -d data/assets/ssl-example/*.pem data/assets/ssl/ -docker-compose up -d -

        +docker-compose up -d

        This will stop mailcow, source the variables we need, create a self-signed certificate and start mailcow.

        If you use Let's Encrypt you should be careful as you will create a new account and a new set of certificates. You will run into a ratelimit sooner or later.

        Please also note that previous TLSA records will be invalid.

        @@ -2504,7 +2503,7 @@ docker-compose up -d - + diff --git a/troubleshooting/debug-rm_volumes/index.html b/troubleshooting/debug-rm_volumes/index.html index fff2b15d8..f72cd217a 100644 --- a/troubleshooting/debug-rm_volumes/index.html +++ b/troubleshooting/debug-rm_volumes/index.html @@ -11,7 +11,7 @@ - + @@ -19,10 +19,10 @@ - + - + @@ -2376,8 +2376,7 @@

        You may want to remove a set of persistent data to resolve a conflict or to start over.

        mailcowdockerized can vary and depends on your compose project name (if it's unchanged, mailcowdockerized is the correct value). If you are unsure about volume names, run docker volume ls for a full list.

        Delete a single volume:

        -
        docker volume rm mailcowdockerized_${VOLUME_NAME}
        -
        +

        docker volume rm mailcowdockerized_${VOLUME_NAME}