diff --git a/material/assets/javascripts/bundle.21e94a31.min.js b/material/assets/javascripts/bundle.21e94a31.min.js deleted file mode 100644 index 05d79846d..000000000 --- a/material/assets/javascripts/bundle.21e94a31.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){function t(t){for(var c,o,i=t[0],s=t[1],b=t[2],u=0,l=[];uObject(y.a)(new ResizeObserver(e=>{for(const t of e)k.next(t)}))).pipe(Object(s.a)(e=>x.a.pipe(Object(v.a)(e)).pipe(Object(_.a)(()=>e.disconnect()))),Object(b.a)(1));function T(e){return{width:e.offsetWidth,height:e.offsetHeight}}function S(e){return{width:e.scrollWidth,height:e.scrollHeight}}function R(e){return A.pipe(Object(E.a)(t=>t.observe(e)),Object(s.a)(t=>k.pipe(Object(o.a)(({target:t})=>t===e),Object(_.a)(()=>t.unobserve(e)),Object(i.a)(({contentRect:e})=>({width:e.width,height:e.height})))),Object(v.a)(T(e)))}function M(e){return{x:e.scrollLeft,y:e.scrollTop}}function C(e,t=16){return function(e){return Object(a.a)(Object(l.a)(e,"scroll"),Object(l.a)(window,"resize")).pipe(Object(i.a)(()=>M(e)),Object(v.a)(M(e)))}(e).pipe(Object(i.a)(({y:n})=>{const c=T(e);return n>=S(e).height-c.height-t}),Object($.a)())}var L=n(42);const P={drawer:O("[data-md-toggle=drawer]"),search:O("[data-md-toggle=search]")};function U(e,t){P[e].checked!==t&&P[e].click()}var N=n(60);function z(){return new URL(location.href)}function H(){return location.hash.substring(1)}function I(e){const t=matchMedia(e);return Object(l.a)(t,"change").pipe(Object(i.a)(e=>e.matches),Object(v.a)(t.matches))}function D(e,t){return e.pipe(Object(s.a)(e=>e?t():x.a))}var Y=n(6);function F(e,t={credentials:"same-origin"}){return Object(Y.a)(fetch(e,t)).pipe(Object(o.a)(e=>200===e.status))}function q(e,t){return F(e,t).pipe(Object(s.a)(e=>e.json()),Object(b.a)(1))}var J=n(46),W=n(61);function B(){return{x:Math.max(0,pageXOffset),y:Math.max(0,pageYOffset)}}function K({x:e,y:t}){window.scrollTo(e||0,t||0)}function Q(){return{width:innerWidth,height:innerHeight}}function X(e,{viewport$:t,header$:n}){const c=t.pipe(Object(W.a)("size")),a=Object(J.a)([c,n]).pipe(Object(i.a)(()=>({x:e.offsetLeft,y:e.offsetTop})));return Object(J.a)([n,t,a]).pipe(Object(i.a)(([{height:e},{offset:t,size:n},{x:c,y:a}])=>({offset:{x:t.x-c,y:t.y-a+e},size:n})))}var V=n(62),G=n(63);const Z=O("#__config"),ee=JSON.parse(Z.textContent);function te(){return ee}function ne(e){return ee.features.includes(e)}function ce(e,t){return void 0!==t?ee.translations[e].replace("#",t.toString()):ee.translations[e]}function ae(e,t=document){return O(`[data-md-component=${e}]`,t)}function re(e,t=document){return h(`[data-md-component=${e}]`,t)}ee.base=new URL(ee.base,z()).toString().replace(/\/$/,"");var oe,ie=n(26),se=n.n(ie),be=n(64);function pe(e,t){e.setAttribute("data-md-state",t)}function ue(e){e.removeAttribute("data-md-state")}function le(e,t){e.classList.toggle("md-nav__link--active",t)}function fe(e){e.classList.remove("md-nav__link--active")}function de(e,t){if("string"==typeof t||"number"==typeof t)e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(const n of t)de(e,n)}function Oe(e,t,...n){const c=document.createElement(e);if(t)for(const e of Object.keys(t))"boolean"!=typeof t[e]?c.setAttribute(e,t[e]):t[e]&&c.setAttribute(e,"");for(const e of n)de(c,e);return c}function je(e){if(e>999){return((e+1e-6)/1e3).toFixed(+((e-950)%1e3>99))+"k"}return e.toString()}function he(e){e.removeAttribute("data-md-state")}function me(e,t){const n=t&oe.PARENT,c=t&oe.TEASER,a=Object.keys(e.terms).filter(t=>!e.terms[t]).map(e=>[Oe("del",null,e)," "]).flat().slice(0,-1);return Oe("a",{href:e.location,class:"md-search-result__link",tabIndex:-1},Oe("article",{class:["md-search-result__article",...n?["md-search-result__article--document"]:[]].join(" "),"data-md-score":e.score.toFixed(2)},n>0&&Oe("div",{class:"md-search-result__icon md-icon"}),Oe("h1",{class:"md-search-result__title"},e.title),c>0&&e.text.length>0&&Oe("p",{class:"md-search-result__teaser"},function(e,t){let n=t;if(e.length>n){for(;" "!==e[n]&&--n>0;);return e.substring(0,n)+"..."}return e}(e.text,320)),c>0&&a.length>0&&Oe("p",{class:"md-search-result__terms"},ce("search.result.term.missing"),": ",a)))}!function(e){e[e.TEASER=1]="TEASER",e[e.PARENT=2]="PARENT"}(oe||(oe={}));let ge=0;function ve(e,t){const n=new c.a;if(n.pipe(Object(be.a)(I("(hover)"))).subscribe(([{scroll:t},n])=>{t&&n?function(e,t=0){e.setAttribute("tabindex",t.toString())}(e):function(e){e.removeAttribute("tabindex")}(e)}),se.a.isSupported()){const t=e.closest("pre");t.id="__code_"+ge++,t.insertBefore((a=t.id,Oe("button",{class:"md-clipboard md-icon",title:ce("clipboard.copy"),"data-clipboard-target":`#${a} > code`})),e)}var a;return function(e,{viewport$:t}){return t.pipe(Object(W.a)("size"),Object(i.a)(()=>{const t=T(e);return{scroll:S(e).width>t.width}}),Object(W.a)("scroll"))}(e,t).pipe(Object(E.a)(n),Object(_.a)(()=>n.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}function we(e,t){const n=new c.a;return n.subscribe(()=>{e.setAttribute("open",""),e.scrollIntoView()}),function(e,{target$:t,print$:n}){return t.pipe(Object(i.a)(e=>e.closest("details:not([open])")),Object(o.a)(t=>e===t),Object(p.a)(n),Object(f.a)(e))}(e,t).pipe(Object(E.a)(n),Object(_.a)(()=>n.complete()),Object(f.a)({ref:e}))}const $e=m("table");function ye(e){return g(e,$e),g($e,Oe("div",{class:"md-typeset__scrollwrap"},Oe("div",{class:"md-typeset__table"},e))),Object(y.a)({ref:e})}var xe=n(77),_e=n(78),Ee=n(66);function ke(e,t){const n=new c.a;return n.pipe(Object(Ee.a)(xe.a)).subscribe(({message:t,open:n})=>{!function(e,t){e.firstElementChild.innerHTML=t}(e,t),n?function(e,t){e.setAttribute("data-md-state",t)}(e,"open"):function(e){e.removeAttribute("data-md-state")}(e)}),function(e,{alert$:t}){return t.pipe(Object(s.a)(e=>Object(a.a)(Object(y.a)(!0),Object(y.a)(!1).pipe(Object(_e.a)(2e3))).pipe(Object(i.a)(t=>({message:e,open:t})))))}(0,t).pipe(Object(E.a)(n),Object(_.a)(()=>n.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var Ae=n(67),Te=n(68);function Se({viewport$:e}){if(!ne("header.autohide"))return Object(y.a)(!1);const t=e.pipe(Object(i.a)(({offset:{y:e}})=>e),Object(Ae.a)(2,1),Object(i.a)(([e,t])=>[eMath.abs(t-e.y)>100),Object(i.a)(([,[e]])=>e),Object($.a)()),c=function(e){const t=P[e];return Object(l.a)(t,"change").pipe(Object(i.a)(()=>t.checked),Object(v.a)(t.checked))}("search");return Object(J.a)([e,c]).pipe(Object(i.a)(([{offset:e},t])=>e.y>400&&!t),Object($.a)(),Object(s.a)(e=>e?n:Object(y.a)(!1)),Object(v.a)(!1))}function Re(e,t){const n=new c.a;n.pipe(Object(Ee.a)(xe.a)).subscribe(({active:t})=>{t?function(e,t){e.setAttribute("data-md-state",t)}(e,"active"):function(e){e.removeAttribute("data-md-state")}(e)});const a=d("article h1");return void 0===a?x.a:function(e,{viewport$:t,header$:n}){return X(e,{header$:n,viewport$:t}).pipe(Object(i.a)(({offset:{y:t}})=>{const{height:n}=T(e);return{active:t>=n}}),Object(W.a)("active"))}(a,t).pipe(Object(E.a)(n),Object(_.a)(()=>n.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var Me=n(71),Ce=n(39),Le=n(3);var Pe=n(17),Ue=n(69),Ne=n(70),ze=n(72),He=n(73),Ie=n(79);var De;n(45);function Ye(e){return e.split(/"([^"]+)"/g).map((e,t)=>1&t?e.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):e).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").trim()}function Fe(e){return e.type===De.READY}function qe(e){return e.type===De.QUERY}function Je(e){return e.type===De.RESULT}function We({config:e,docs:t,index:n}){1===e.lang.length&&"en"===e.lang[0]&&(e.lang=[ce("search.config.lang")]),"[\\s\\-]+"===e.separator&&(e.separator=ce("search.config.separator"));return{config:e,docs:t,index:n,pipeline:ce("search.config.pipeline").split(/\s*,\s*/).filter(Boolean)}}function Be(e,t){const n=te(),a=new Worker(e),r=new c.a,o=function(e,{tx$:t}){const n=Object(l.a)(e,"message").pipe(Object(i.a)(({data:e})=>e));return t.pipe(Object(V.a)(()=>n,{leading:!0,trailing:!0}),Object(E.a)(t=>e.postMessage(t)),Object(G.a)(n),Object(L.a)())}(a,{tx$:r}).pipe(Object(i.a)(e=>{if(Je(e))for(const t of e.data)for(const e of t)e.location=`${n.base}/${e.location}`;return e}),Object(L.a)());return Object(Y.a)(t).pipe(Object(i.a)(e=>({type:De.SETUP,data:We(e)}))).subscribe(r.next.bind(r)),{tx$:r,rx$:o}}!function(e){e[e.SETUP=0]="SETUP",e[e.READY=1]="READY",e[e.QUERY=2]="QUERY",e[e.RESULT=3]="RESULT"}(De||(De={}));var Ke=n(74),Qe=n(75);function Xe(e){const t=(null===__search||void 0===__search?void 0:__search.transform)||Ye,n=function(e){return Object(a.a)(Object(l.a)(e,"focus"),Object(l.a)(e,"blur")).pipe(Object(i.a)(({type:e})=>"focus"===e),Object(v.a)(e===j()))}(e),c=Object(a.a)(Object(l.a)(e,"keyup"),Object(l.a)(e,"focus").pipe(Object(_e.a)(1))).pipe(Object(i.a)(()=>t(e.value)),Object(v.a)(t(e.value)),Object($.a)());return Object(J.a)([c,n]).pipe(Object(i.a)(([e,t])=>({value:e,focus:t})))}function Ve(e,{tx$:t}){const n=new c.a;return n.pipe(Object(W.a)("value"),Object(i.a)(({value:e})=>({type:De.QUERY,data:e}))).subscribe(t.next.bind(t)),n.pipe(Object(W.a)("focus")).subscribe(({focus:t})=>{t?(U("search",t),function(e,t){e.placeholder=t}(e,"")):function(e){e.placeholder=ce("search.placeholder")}(e)}),Object(l.a)(e.form,"reset").pipe(Object(Ke.a)(n.pipe(Object(Qe.a)(1)))).subscribe(()=>w(e)),Xe(e).pipe(Object(E.a)(n),Object(_.a)(()=>n.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var Ge=n(80);function Ze(e,{rx$:t},{query$:n}){const r=new c.a,b=C(e.parentElement).pipe(Object(o.a)(Boolean)),p=O(":scope > :first-child",e);r.pipe(Object(Ee.a)(xe.a),Object(be.a)(n)).subscribe(([{data:e},{value:t}])=>{t?function(e,t){switch(t){case 0:e.textContent=ce("search.result.none");break;case 1:e.textContent=ce("search.result.one");break;default:e.textContent=ce("search.result.other",je(t))}}(p,e.length):function(e){e.textContent=ce("search.result.placeholder")}(p)});const u=O(":scope > :last-child",e);r.pipe(Object(Ee.a)(xe.a),Object(E.a)(()=>function(e){e.innerHTML=""}(u)),Object(s.a)(({data:e})=>Object(a.a)(Object(y.a)(...e.slice(0,10)),Object(y.a)(...e.slice(10)).pipe(Object(Ae.a)(4),Object(Ge.a)(b),Object(s.a)(([e])=>Object(y.a)(...e)))))).subscribe(e=>{!function(e,t){e.appendChild(t)}(u,function(e){const t=e[0].score,n=[...e],c=n.findIndex(e=>!e.location.includes("#")),[a]=n.splice(c,1);let r=n.findIndex(e=>e.scoreme(e,oe.TEASER)),...i.length?[Oe("details",{class:"md-search-result__more"},Oe("summary",{tabIndex:-1},i.length>0&&1===i.length?ce("search.result.more.one"):ce("search.result.more.other",i.length)),i.map(e=>me(e,oe.TEASER)))]:[]];return Oe("li",{class:"md-search-result__item"},s)}(e))});return t.pipe(Object(o.a)(Je),Object(i.a)(({data:e})=>({data:e})),Object(v.a)({data:[]})).pipe(Object(E.a)(r),Object(_.a)(()=>r.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}function et(e,{keyboard$:t}){if("file:"===location.protocol)return x.a;const n=te(),c=Be(n.search,(r=n.base+"/search/search_index.json",(null===__search||void 0===__search?void 0:__search.index)||q(r)));var r;const i=ae("search-query",e),s=ae("search-result",e),{tx$:b,rx$:p}=c;b.pipe(Object(o.a)(qe),Object(Me.a)(p.pipe(Object(o.a)(Fe))),Object(Ce.a)(1)).subscribe(b.next.bind(b)),t.pipe(Object(o.a)(({mode:e})=>"search"===e)).subscribe(e=>{const t=j();switch(e.type){case"Enter":t===i&&e.claim();break;case"Escape":case"Tab":U("search",!1),w(i,!1);break;case"ArrowUp":case"ArrowDown":if(void 0===t)w(i);else{const n=[i,...h(":not(details) > [href], summary, details[open] [href]",s)],c=Math.max(0,(Math.max(0,n.indexOf(t))+n.length+("ArrowUp"===e.type?-1:1))%n.length);w(n[c])}e.claim();break;default:i!==j()&&w(i)}}),t.pipe(Object(o.a)(({mode:e})=>"global"===e)).subscribe(e=>{switch(e.type){case"f":case"s":case"/":w(i),function(e){if(!(e instanceof HTMLInputElement))throw new Error("Not implemented");e.select()}(i),e.claim()}});const u=Ve(i,c);return Object(a.a)(u,Ze(s,c,{query$:u}))}var tt=n(25);function nt(e,t){var{header$:n}=t,a=Object(tt.c)(t,["header$"]);const r=new c.a;return r.pipe(Object(Ee.a)(xe.a),Object(be.a)(n)).subscribe({next([{height:t},{height:n}]){!function(e,t){const n=e.firstElementChild;n.style.height=t-2*n.offsetTop+"px"}(e,t),function(e,t){e.style.top=t+"px"}(e,n)},complete(){!function(e){e.style.top=""}(e),function(e){e.firstElementChild.style.height=""}(e)}}),function(e,{viewport$:t,main$:n}){const c=e.parentElement.offsetTop-e.parentElement.parentElement.offsetTop;return Object(J.a)([n,t]).pipe(Object(i.a)(([{offset:e,height:t},{offset:{y:n}}])=>({height:t=t+Math.min(c,Math.max(0,n-e))-c,locked:n>=e+c})),Object($.a)((e,t)=>e.height===t.height&&e.locked===t.locked))}(e,a).pipe(Object(E.a)(r),Object(_.a)(()=>r.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var ct=n(76);function at(e){const[t]=e.match(/(git(?:hub|lab))/i)||[];switch(t.toLowerCase()){case"github":const[,t,n]=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);return function(e,t){return q(void 0!==t?`https://api.github.com/repos/${e}/${t}`:"https://api.github.com/users/"+e).pipe(Object(i.a)(e=>{if(void 0!==t){const{stargazers_count:t,forks_count:n}=e;return[je(t)+" Stars",je(n)+" Forks"]}{const{public_repos:t}=e;return[je(t)+" Repositories"]}}),Object(ct.a)([]))}(t,n);case"gitlab":const[,c,a]=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i);return function(e,t){return q(`https://${e}/api/v4/projects/${encodeURIComponent(t)}`).pipe(Object(i.a)(({star_count:e,forks_count:t})=>[je(e)+" Stars",je(t)+" Forks"]),Object(ct.a)([]))}(c,a);default:return x.a}}let rt;function ot(e){const t=new c.a;return t.subscribe(({facts:t})=>{!function(e,t){e.lastElementChild.appendChild(t)}(e,function(e){return Oe("ul",{class:"md-source__facts"},e.map(e=>Oe("li",{class:"md-source__fact"},e)))}(t)),function(e,t){e.lastElementChild.setAttribute("data-md-state",t)}(e,"done")}),function(e){const t=function(e){let t=0;for(let n=0,c=e.length;n{const n=sessionStorage.getItem(t);if(n)return Object(y.a)(JSON.parse(n));{const n=at(e.href);return n.subscribe(e=>{try{sessionStorage.setItem(t,JSON.stringify(e))}catch(e){}}),n}}).pipe(Object(Ne.a)(()=>x.a),Object(o.a)(e=>e.length>0),Object(i.a)(e=>({facts:e})),Object(b.a)(1)))}(e).pipe(Object(E.a)(t),Object(_.a)(()=>t.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}function it(e,t){const n=new c.a;return n.pipe(Object(Ee.a)(xe.a)).subscribe({next({hidden:t}){t?function(e,t){e.setAttribute("data-md-state",t)}(e,"hidden"):he(e)},complete(){he(e)}}),function(e,{viewport$:t,header$:n}){return X(e,{header$:n,viewport$:t}).pipe(Object(i.a)(({offset:{y:e}})=>({hidden:e>=10})),Object(W.a)("hidden"))}(e,t).pipe(Object(E.a)(n),Object(_.a)(()=>n.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var st=n(81);function bt(e,t){const n=new c.a;n.pipe(Object(Ee.a)(xe.a)).subscribe(({prev:e,next:t})=>{for(const[e]of t)fe(e),ue(e);for(const[t,[n]]of e.entries())le(n,t===e.length-1),pe(n,"blur")});return function(e,{viewport$:t,header$:n}){const c=new Map;for(const t of e){const e=d(`[id="${decodeURIComponent(t.hash.substring(1))}"]`);void 0!==e&&c.set(t,e)}const a=n.pipe(Object(i.a)(e=>24+e.height));return R(document.body).pipe(Object(W.a)("height"),Object(i.a)(()=>{let e=[];return[...c].reduce((t,[n,a])=>{for(;e.length;){if(!(c.get(e[e.length-1]).tagName>=a.tagName))break;e.pop()}let r=a.offsetTop;for(;!r&&a.parentElement;)r=(a=a.parentElement).offsetTop;return t.set([...e=[...e,n]].reverse(),r)},new Map)}),Object(s.a)(e=>Object(J.a)([a,t]).pipe(Object(st.a)(([e,t],[n,{offset:{y:c}}])=>{for(;t.length;){const[,a]=t[0];if(!(a-n=c))break;t=[e.pop(),...t]}return[e,t]},[[],[...e]]),Object($.a)((e,t)=>e[0]===t[0]&&e[1]===t[1])))).pipe(Object(i.a)(([e,t])=>({prev:e.map(([e])=>e),next:t.map(([e])=>e)})),Object(v.a)({prev:[],next:[]}),Object(Ae.a)(2,1),Object(i.a)(([e,t])=>e.prev.lengthn.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var pt=n(14);function ut(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}document.documentElement.classList.remove("no-js"),document.documentElement.classList.add("js");const lt=function(){const e=new u.a;return Object(l.a)(document,"DOMContentLoaded").pipe(Object(f.a)(document)).subscribe(e),e}(),ft=new N.a(z()),dt=Object(l.a)(window,"hashchange").pipe(Object(i.a)(H),Object(v.a)(H()),Object(o.a)(e=>e.length>0),Object(L.a)()).pipe(Object(s.a)(e=>Object(y.a)(d(`[id="${e}"]`)))),Ot=Object(l.a)(window,"keydown").pipe(Object(o.a)(e=>!(e.metaKey||e.ctrlKey)),Object(i.a)(e=>{return{mode:(t="search",P[t].checked?"search":"global"),type:e.key,claim(){e.preventDefault(),e.stopPropagation()}};var t}),Object(o.a)(({mode:e})=>{if("global"===e){const e=j();if(void 0!==e)return!function(e){switch(e.tagName){case"INPUT":case"SELECT":case"TEXTAREA":return!0;default:return e.isContentEditable}}(e)}return!0}),Object(L.a)()),jt=Object(J.a)([Object(a.a)(Object(l.a)(window,"scroll",{passive:!0}),Object(l.a)(window,"resize",{passive:!0})).pipe(Object(i.a)(B),Object(v.a)(B())),Object(l.a)(window,"resize",{passive:!0}).pipe(Object(i.a)(Q),Object(v.a)(Q()))]).pipe(Object(i.a)(([e,t])=>({offset:e,size:t})),Object(b.a)(1)),ht=I("(min-width: 960px)"),mt=I("(min-width: 1220px)"),gt=Object(a.a)(I("print").pipe(Object(o.a)(Boolean)),Object(l.a)(window,"beforeprint")).pipe(Object(f.a)(void 0)),vt=new c.a;!function({alert$:e}){se.a.isSupported()&&new Le.a(e=>{new se.a("[data-clipboard-target], [data-clipboard-text]").on("success",t=>e.next(t))}).subscribe(()=>e.next(ce("clipboard.copied")))}({alert$:vt}),ne("navigation.instant")&&function({document$:e,location$:t,viewport$:n}){const c=te();if("file:"===location.protocol)return;"scrollRestoration"in history&&(history.scrollRestoration="manual",Object(l.a)(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}));const r=d("link[rel='shortcut icon']");void 0!==r&&(r.href=r.href);const p=function(e,t){const n=new DOMParser;return F(e,t).pipe(Object(s.a)(e=>e.text()),Object(i.a)(e=>n.parseFromString(e,"text/xml")),Object(b.a)(1))}(c.base+"/sitemap.xml").pipe(Object(i.a)(e=>function(e){if(e.length<2)return e;const[t,n]=e.sort((e,t)=>e.length-t.length);let c=0;if(t===n)c=t.length;else for(;t.charCodeAt(c)==t.charCodeAt(c);)c++;const a=te();return e.map(e=>e.replace(t.slice(0,c),a.base+"/"))}(h("loc",e).map(e=>e.textContent))),Object(s.a)(e=>Object(l.a)(document.body,"click").pipe(Object(o.a)(e=>!e.metaKey&&!e.ctrlKey),Object(s.a)(t=>{if(t.target instanceof HTMLElement){const n=t.target.closest("a");if(n&&!n.target&&e.includes(n.href))return t.preventDefault(),Object(y.a)({url:new URL(n.href)})}return x.a}))),Object(L.a)()),u=Object(l.a)(window,"popstate").pipe(Object(o.a)(e=>null!==e.state),Object(i.a)(e=>({url:new URL(location.href),offset:e.state})),Object(L.a)());Object(a.a)(p,u).pipe(Object($.a)((e,t)=>e.url.href===t.url.href),Object(i.a)(({url:e})=>e)).subscribe(t);const f=t.pipe(Object(W.a)("pathname"),Object(Ue.a)(1),Object(s.a)(e=>F(e.href).pipe(Object(Ne.a)(()=>(function(e){location.href=e.href}(e),x.a)))),Object(L.a)());p.pipe(Object(Me.a)(f)).subscribe(({url:e})=>{history.pushState({},"",e.toString())});const O=new DOMParser;f.pipe(Object(s.a)(e=>e.text()),Object(i.a)(e=>O.parseFromString(e,"text/html"))).subscribe(e),Object(a.a)(p,u).pipe(Object(Me.a)(e)).subscribe(({url:e,offset:t})=>{e.hash&&!t?function(e){const t=m("a");t.href=e,t.addEventListener("click",e=>e.stopPropagation()),t.click()}(e.hash):K(t||{y:0})}),e.pipe(Object(Ue.a)(1)).subscribe(e=>{for(const t of["title","link[rel='canonical']","meta[name='author']","meta[name='description']","[data-md-component=announce]","[data-md-component=header-title]","[data-md-component=container]","[data-md-component=skip]"]){const n=d(t),c=d(t,e);void 0!==n&&void 0!==c&&g(n,c)}}),e.pipe(Object(Ue.a)(1),Object(i.a)(()=>ae("container")),Object(s.a)(e=>Object(y.a)(...h("script",e))),Object(ze.a)(e=>{const t=m("script");return e.src?(t.src=e.src,g(e,t),new Le.a(e=>{t.onload=()=>e.complete()})):(t.textContent=e.textContent,g(e,t),Pe.a)})).subscribe(),n.pipe(Object(He.a)(p),Object(Ie.a)(250),Object(W.a)("offset")).subscribe(({offset:e})=>{history.replaceState(e,"")}),Object(a.a)(p,u).pipe(Object(Ae.a)(2,1),Object(o.a)(([e,t])=>e.url.pathname===t.url.pathname),Object(i.a)(([,e])=>e)).subscribe(({offset:e})=>{K(e||{y:0})})}({document$:lt,location$:ft,viewport$:jt}),Object(a.a)(ft,dt).subscribe(()=>U("drawer",!1)),Ot.pipe(Object(o.a)(({mode:e})=>"global"===e)).subscribe(e=>{switch(e.type){case"p":case",":const e=d("[href][rel=prev]");void 0!==e&&e.click();break;case"n":case".":const t=d("[href][rel=next]");void 0!==t&&t.click()}}),function({document$:e}){e.subscribe(()=>{for(const e of h("[data-md-state=indeterminate]"))e.setAttribute("data-md-state",""),e.indeterminate=!0,e.checked=!1})}({document$:lt}),function({document$:e}){e.pipe(Object(s.a)(()=>Object(y.a)(...h("[data-md-scrollfix]"))),Object(E.a)(e=>e.removeAttribute("data-md-scrollfix")),Object(o.a)(ut),Object(pt.a)(e=>Object(l.a)(e,"touchstart").pipe(Object(f.a)(e)))).subscribe(e=>{const t=e.scrollTop;0===t?e.scrollTop=1:t+e.offsetHeight===e.scrollHeight&&(e.scrollTop=t-1)})}({document$:lt});const wt=($t=ae("header"),yt={viewport$:jt},Object(r.a)(()=>{const e=getComputedStyle($t);return Object(y.a)("sticky"===e.position||"-webkit-sticky"===e.position)}).pipe(Object(Te.a)(R($t),Se(yt)),Object(i.a)(([e,{height:t},n])=>({height:e?t:0,sticky:e,hidden:n})),Object($.a)((e,t)=>e.sticky===t.sticky&&e.height===t.height&&e.hidden===t.hidden),Object(b.a)(1)));var $t,yt;const xt=lt.pipe(Object(i.a)(()=>ae("main")),Object(s.a)(e=>function(e,{viewport$:t,header$:n}){const c=n.pipe(Object(i.a)(({height:e})=>e),Object($.a)()),a=c.pipe(Object(s.a)(()=>R(e).pipe(Object(i.a)(({height:t})=>({top:e.offsetTop,bottom:e.offsetTop+t})),Object(W.a)("bottom"))));return Object(J.a)([c,a,t]).pipe(Object(i.a)(([e,{top:t,bottom:n},{offset:{y:c},size:{height:a}}])=>({offset:t-e,height:a=Math.max(0,a-Math.max(0,t-c,e)-Math.max(0,a+c-n)),active:t-e<=c})),Object($.a)((e,t)=>e.offset===t.offset&&e.height===t.height&&e.active===t.active))}(e,{viewport$:jt,header$:wt})),Object(b.a)(1)),_t=Object(a.a)(...re("dialog").map(e=>ke(e,{alert$:vt})),...re("header").map(e=>function(e,{header$:t,main$:n}){const a=new c.a;return a.pipe(Object(W.a)("active"),Object(Te.a)(t),Object(Ee.a)(xe.a)).subscribe(([{active:t},{hidden:n}])=>{t?function(e,t){e.setAttribute("data-md-state",t)}(e,n?"hidden":"shadow"):function(e){e.removeAttribute("data-md-state")}(e)}),n.subscribe(e=>a.next(e)),t.pipe(Object(i.a)(t=>Object.assign({ref:e},t)))}(e,{viewport$:jt,header$:wt,main$:xt})),...re("search").map(e=>et(e,{keyboard$:Ot})),...re("source").map(e=>ot(e)),...re("tabs").map(e=>it(e,{viewport$:jt,header$:wt}))),Et=Object(r.a)(()=>Object(a.a)(...re("content").map(e=>function(e,{target$:t,viewport$:n,print$:c}){return Object(a.a)(...h("pre > code",e).map(e=>ve(e,{viewport$:n})),...h("table:not([class])",e).map(e=>ye(e)),...h("details",e).map(e=>we(e,{target$:t,print$:c})))}(e,{target$:dt,viewport$:jt,print$:gt})),...re("header-title").map(e=>Re(e,{viewport$:jt,header$:wt})),...re("sidebar").map(e=>"navigation"===e.getAttribute("data-md-type")?D(mt,()=>nt(e,{viewport$:jt,header$:wt,main$:xt})):D(ht,()=>nt(e,{viewport$:jt,header$:wt,main$:xt}))),...re("toc").map(e=>bt(e,{viewport$:jt,header$:wt})))),kt=lt.pipe(Object(s.a)(()=>Et),Object(p.a)(_t),Object(b.a)(1));kt.subscribe()}})); -//# sourceMappingURL=bundle.21e94a31.min.js.map \ No newline at end of file diff --git a/material/assets/javascripts/bundle.21e94a31.min.js.map b/material/assets/javascripts/bundle.21e94a31.min.js.map deleted file mode 100644 index 6801e5054..000000000 --- a/material/assets/javascripts/bundle.21e94a31.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/assets/javascripts/browser/element/_/index.ts","webpack:///./src/assets/javascripts/browser/element/focus/index.ts","webpack:///./src/assets/javascripts/browser/element/size/index.ts","webpack:///./src/assets/javascripts/browser/element/offset/index.ts","webpack:///./src/assets/javascripts/browser/toggle/index.ts","webpack:///./src/assets/javascripts/browser/location/_/index.ts","webpack:///./src/assets/javascripts/browser/location/hash/index.ts","webpack:///./src/assets/javascripts/browser/media/index.ts","webpack:///./src/assets/javascripts/browser/request/index.ts","webpack:///./src/assets/javascripts/browser/viewport/offset/index.ts","webpack:///./src/assets/javascripts/browser/viewport/size/index.ts","webpack:///./src/assets/javascripts/browser/viewport/_/index.ts","webpack:///./src/assets/javascripts/_/index.ts","webpack:///./src/assets/javascripts/components/_/index.ts","webpack:///./src/assets/javascripts/templates/search/index.tsx","webpack:///./src/assets/javascripts/actions/anchor/index.ts","webpack:///./src/assets/javascripts/utilities/h/index.ts","webpack:///./src/assets/javascripts/utilities/string/index.ts","webpack:///./src/assets/javascripts/actions/tabs/index.ts","webpack:///./src/assets/javascripts/components/content/code/index.ts","webpack:///./src/assets/javascripts/actions/_/index.ts","webpack:///./src/assets/javascripts/templates/clipboard/index.tsx","webpack:///./src/assets/javascripts/components/content/details/index.ts","webpack:///./src/assets/javascripts/components/content/table/index.ts","webpack:///./src/assets/javascripts/templates/table/index.tsx","webpack:///./src/assets/javascripts/components/dialog/index.ts","webpack:///./src/assets/javascripts/actions/dialog/index.ts","webpack:///./src/assets/javascripts/components/header/_/index.ts","webpack:///./src/assets/javascripts/components/header/title/index.ts","webpack:///./src/assets/javascripts/actions/header/title/index.ts","webpack:///./src/assets/javascripts/integrations/search/worker/message/index.ts","webpack:///./src/assets/javascripts/integrations/search/query/transform/index.ts","webpack:///./src/assets/javascripts/integrations/search/worker/_/index.ts","webpack:///./src/assets/javascripts/browser/worker/index.ts","webpack:///./src/assets/javascripts/components/search/query/index.ts","webpack:///./src/assets/javascripts/actions/search/query/index.ts","webpack:///./src/assets/javascripts/components/search/result/index.ts","webpack:///./src/assets/javascripts/actions/search/result/index.ts","webpack:///./src/assets/javascripts/components/search/_/index.ts","webpack:///./src/assets/javascripts/browser/element/selection/index.ts","webpack:///./src/assets/javascripts/components/sidebar/index.ts","webpack:///./src/assets/javascripts/actions/sidebar/index.ts","webpack:///./src/assets/javascripts/components/source/facts/_/index.ts","webpack:///./src/assets/javascripts/components/source/facts/github/index.ts","webpack:///./src/assets/javascripts/components/source/facts/gitlab/index.ts","webpack:///./src/assets/javascripts/components/source/_/index.ts","webpack:///./src/assets/javascripts/actions/source/index.ts","webpack:///./src/assets/javascripts/templates/source/index.tsx","webpack:///./src/assets/javascripts/components/tabs/index.ts","webpack:///./src/assets/javascripts/components/toc/index.ts","webpack:///./src/assets/javascripts/patches/scrollfix/index.ts","webpack:///./src/assets/javascripts/index.ts","webpack:///./src/assets/javascripts/browser/document/index.ts","webpack:///./src/assets/javascripts/browser/keyboard/index.ts","webpack:///./src/assets/javascripts/integrations/clipboard/index.ts","webpack:///./src/assets/javascripts/integrations/instant/index.ts","webpack:///./src/assets/javascripts/patches/indeterminate/index.ts","webpack:///./src/assets/javascripts/components/main/index.ts","webpack:///./src/assets/javascripts/actions/header/_/index.ts","webpack:///./src/assets/javascripts/components/content/_/index.ts"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","0","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","window","oldJsonpFunction","slice","getElement","selector","node","document","querySelector","undefined","getElementOrThrow","el","ReferenceError","getActiveElement","activeElement","HTMLElement","getElements","Array","from","querySelectorAll","createElement","tagName","replaceElement","source","target","replaceWith","setElementFocus","focus","blur","entry$","Subject","observer$","defer","of","ResizeObserver","entries","entry","next","pipe","switchMap","resize","startWith","finalize","disconnect","shareReplay","getElementSize","width","offsetWidth","height","offsetHeight","getElementContentSize","scrollWidth","scrollHeight","watchElementSize","tap","observer","observe","filter","unobserve","map","contentRect","getElementOffset","x","scrollLeft","y","scrollTop","watchElementThreshold","threshold","merge","fromEvent","watchElementOffset","visible","distinctUntilChanged","toggles","drawer","search","setToggle","checked","click","getLocation","URL","location","href","getLocationHash","hash","substring","watchMedia","query","media","matchMedia","ev","matches","at","query$","factory","active","request","url","options","credentials","fetch","res","status","requestJSON","json","getViewportOffset","Math","max","pageXOffset","pageYOffset","setViewportOffset","scrollTo","getViewportSize","innerWidth","innerHeight","watchViewportAt","viewport$","header$","size$","distinctUntilKeyChanged","offset$","combineLatest","offsetLeft","offsetTop","offset","size","JSON","parse","textContent","configuration","feature","flag","features","includes","translation","translations","replace","toString","getComponentElement","type","getComponentElements","base","Flag","setAnchorState","state","setAttribute","resetAnchorState","removeAttribute","setAnchorActive","classList","toggle","resetAnchorActive","remove","appendChild","child","innerHTML","Node","isArray","h","tag","attributes","children","attr","keys","round","toFixed","resetTabsState","renderSearchDocument","parent","PARENT","teaser","TEASER","missing","terms","flat","class","tabIndex","join","score","title","text","truncate","mountCodeBlock","internal$","withLatestFrom","subscribe","scroll","hover","setFocusable","resetFocusable","isSupported","closest","id","insertBefore","watchCodeBlock","complete","ref","mountDetails","scrollIntoView","target$","print$","details","mergeWith","mapTo","watchDetails","sentinel","mountDataTable","mountDialog","observeOn","animationFrame","message","open","firstElementChild","setDialogMessage","setDialogState","resetDialogState","_el","alert$","delay","watchDialog","isHidden","direction$","bufferCount","a","b","hidden$","abs","direction","search$","watchToggle","mountHeaderTitle","setHeaderTitleState","resetHeaderTitleState","headline","watchHeaderTitle","SearchMessageType","defaultTransform","split","index","trim","isSearchReadyMessage","READY","isSearchQueryMessage","QUERY","isSearchResultMessage","RESULT","setupSearchIndex","config","docs","lang","separator","pipeline","Boolean","setupSearchWorker","worker","Worker","tx$","rx$","throttle","leading","trailing","postMessage","switchMapTo","share","watchWorker","SETUP","watchSearchQuery","fn","__search","transform","focus$","watchElementFocus","value$","mountSearchQuery","placeholder","setSearchQueryPlaceholder","resetSearchQueryPlaceholder","form","takeUntil","takeLast","mountSearchResult","boundary$","parentElement","meta","setSearchResultMeta","resetSearchResultMeta","list","resetSearchResultList","zipWith","chunk","addToSearchResultList","findIndex","doc","article","best","more","section","renderSearchResult","mountSearch","keyboard$","protocol","sample","take","claim","els","indexOf","HTMLInputElement","Error","select","setElementSelection","mountSidebar","scrollwrap","style","setSidebarHeight","top","setSidebarOffset","resetSidebarOffset","resetSidebarHeight","main$","adjust","min","locked","watchSidebar","fetchSourceFacts","match","toLowerCase","user","repo","stargazers_count","forks_count","public_repos","defaultIfEmpty","fetchSourceFactsFromGitHub","slug","project","encodeURIComponent","star_count","fetchSourceFactsFromGitLab","fetch$","mountSource","facts","lastElementChild","setSourceFacts","fact","renderSourceFacts","setSourceState","digest","len","charCodeAt","sessionStorage","getItem","setItem","stringify","err","catchError","watchSource","mountTabs","hidden","setTabsState","watchTabs","mountTableOfContents","prev","anchor","anchors","table","Map","decodeURIComponent","set","adjust$","header","body","path","reduce","pop","reverse","scan","watchTableOfContents","isAppleDevice","test","navigator","userAgent","documentElement","add","document$","ReplaySubject","watchDocument","BehaviorSubject","metaKey","ctrlKey","preventDefault","stopPropagation","isContentEditable","isSusceptibleToKeyboard","passive","tablet$","screen$","Observable","subscriber","on","setupClipboardJS","location$","history","scrollRestoration","favicon","push$","dom","DOMParser","parseFromString","requestXML","sitemap","urls","root","sort","preprocess","pop$","response$","skip","setLocation","pushState","addEventListener","setLocationHash","replacement","concatMap","script","src","onload","skipUntil","debounceTime","replaceState","pathname","setupInstantLoading","indeterminate","patchIndeterminate","mergeMap","patchScrollfix","styles","getComputedStyle","position","combineLatestWith","sticky","border$","bottom","watchMain","control$","setHeaderState","resetHeaderState","main","mountHeader","content$","mountContent","getAttribute","component$"],"mappings":"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","file":"assets/javascripts/bundle.21e94a31.min.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t0: 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([50,1]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","/*\n * Copyright (c) 2016-2021 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 an 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 getElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElement(\n selector: string, node?: ParentNode\n): T | undefined\n\nexport function getElement(\n selector: string, node: ParentNode = document\n): T | undefined {\n return node.querySelector(selector) || undefined\n}\n\n/**\n * Retrieve an element matching a query selector or throw a reference error\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 getElementOrThrow(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElementOrThrow(\n selector: string, node?: ParentNode\n): T\n\nexport function getElementOrThrow(\n selector: string, node: ParentNode = document\n): T {\n const el = getElement(selector, node)\n if (typeof el === \"undefined\")\n throw new ReferenceError(\n `Missing element: expected \"${selector}\" to be present`\n )\n return el\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\n : undefined\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\n/**\n * Create an element\n *\n * @template T - Tag name type\n *\n * @param tagName - Tag name\n *\n * @returns Element\n */\nexport function createElement(\n tagName: T\n): HTMLElementTagNameMap[T] {\n return document.createElement(tagName)\n}\n\n/**\n * Replace an element with another element\n *\n * @param source - Source element\n * @param target - Target element\n */\nexport function replaceElement(\n source: HTMLElement, target: Node\n): void {\n source.replaceWith(target)\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent, merge } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\nimport { getActiveElement } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set element focus\n *\n * @param el - Element\n * @param value - Whether the element should be focused\n */\nexport function setElementFocus(\n el: HTMLElement, value = true\n): void {\n if (value)\n el.focus()\n else\n el.blur()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element focus\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(el, \"focus\"),\n fromEvent(el, \"blur\")\n )\n .pipe(\n map(({ type }) => type === \"focus\"),\n startWith(el === getActiveElement())\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 of\n} from \"rxjs\"\nimport {\n filter,\n finalize,\n map,\n shareReplay,\n startWith,\n switchMap,\n tap\n} from \"rxjs/operators\"\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(resize => NEVER.pipe(startWith(resize))\n .pipe(\n finalize(() => resize.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(el: HTMLElement): ElementSize {\n return {\n width: el.offsetWidth,\n height: el.offsetHeight\n }\n}\n\n/**\n * Retrieve element content size, i.e. including overflowing content\n *\n * @param el - Element\n *\n * @returns Element size\n */\nexport function getElementContentSize(el: HTMLElement): ElementSize {\n return {\n width: el.scrollWidth,\n height: el.scrollHeight\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 * @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(({ contentRect }) => ({\n width: contentRect.width,\n height: contentRect.height\n }))\n )\n ),\n startWith(getElementSize(el))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent, merge } from \"rxjs\"\nimport { distinctUntilChanged, map, startWith } from \"rxjs/operators\"\n\nimport { getElementContentSize, getElementSize } from \"../size\"\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(el: HTMLElement): ElementOffset {\n return {\n x: el.scrollLeft,\n y: el.scrollTop\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(el, \"scroll\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n map(() => getElementOffset(el)),\n startWith(getElementOffset(el))\n )\n}\n\n/**\n * Watch element threshold\n *\n * This function returns an observable which emits whether the bottom scroll\n * offset of an elements is within a certain threshold.\n *\n * @param el - Element\n * @param threshold - Threshold\n *\n * @returns Element threshold observable\n */\nexport function watchElementThreshold(\n el: HTMLElement, threshold = 16\n): Observable {\n return watchElementOffset(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-2021 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, fromEvent } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\nimport { getElementOrThrow } 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: getElementOrThrow(\"[data-md-toggle=drawer]\"),\n search: getElementOrThrow(\"[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-2021 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 { BehaviorSubject, Subject } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location\n *\n * This function will return a `URL` object (and not `Location`) in order to\n * normalize typings across the application. Furthermore, locations need to be\n * tracked without setting them and `Location` is a singleton which represents\n * the 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 BehaviorSubject(getLocation())\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent, of } from \"rxjs\"\nimport { filter, map, share, startWith, switchMap } from \"rxjs/operators\"\n\nimport { createElement, getElement } from \"~/browser\"\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 = createElement(\"a\")\n el.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 share()\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 switchMap(id => of(getElement(`[id=\"${id}\"]`)!))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { NEVER, Observable, fromEvent, merge } from \"rxjs\"\nimport {\n filter,\n map,\n mapTo,\n startWith,\n switchMap\n} from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch media query\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 fromEvent(media, \"change\")\n .pipe(\n map(ev => ev.matches),\n startWith(media.matches)\n )\n}\n\n/**\n * Watch print mode, cross-browser\n *\n * @returns Print observable\n */\nexport function watchPrint(): Observable {\n return merge(\n watchMedia(\"print\").pipe(filter(Boolean)), /* Webkit */\n fromEvent(window, \"beforeprint\") /* IE, FF */\n )\n .pipe(\n mapTo(undefined)\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() : NEVER)\n )\n}\n","/*\n * Copyright (c) 2016-2021 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, from } from \"rxjs\"\nimport {\n filter,\n map,\n shareReplay,\n switchMap\n} from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the given URL\n *\n * @param url - Request URL\n * @param options - Request options\n *\n * @returns Response observable\n */\nexport function request(\n url: string, options: RequestInit = { credentials: \"same-origin\" }\n): Observable {\n return from(fetch(url, options))\n .pipe(\n filter(res => res.status === 200),\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 - Request options\n *\n * @returns Data observable\n */\nexport function requestJSON(\n 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 - Request options\n *\n * @returns Data observable\n */\nexport function requestXML(\n 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-2021 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, fromEvent, merge } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\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, pageXOffset),\n y: Math.max(0, pageYOffset)\n }\n}\n\n/**\n * Set viewport offset\n *\n * @param offset - Viewport offset\n */\nexport function setViewportOffset(\n { x, y }: Partial\n): void {\n window.scrollTo(x || 0, y || 0)\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-2021 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, fromEvent } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\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-2021 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, combineLatest } from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n map,\n shareReplay\n} from \"rxjs/operators\"\n\nimport { Header } from \"~/components\"\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 * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch at options\n */\ninterface WatchAtOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
/* Header observable */\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/**\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$ }: WatchAtOptions\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((): ViewportOffset => ({\n x: el.offsetLeft,\n y: el.offsetTop\n }))\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-2021 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 { getElementOrThrow, getLocation } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flag\n */\nexport type Flag =\n | \"header.autohide\" /* Hide header */\n | \"navigation.expand\" /* Automatic expansion */\n | \"navigation.instant\" /* Instant loading */\n | \"navigation.sections\" /* Sections navigation */\n | \"navigation.tabs\" /* Tabs navigation */\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\n/**\n * Translations\n */\nexport type Translations = Record\n\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}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration and make base URL absolute\n */\nconst script = getElementOrThrow(\"#__config\")\nconst config: Config = JSON.parse(script.textContent!)\nconfig.base = new URL(config.base, getLocation())\n .toString()\n .replace(/\\/$/, \"\")\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 - Value to be replaced\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-2021 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 { getElementOrThrow, getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component\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 | \"main\" /* Main area */\n | \"search\" /* Search */\n | \"search-query\" /* Search input */\n | \"search-result\" /* Search results */\n | \"sidebar\" /* Sidebar */\n | \"skip\" /* Skip link */\n | \"source\" /* Repository information */\n | \"tabs\" /* Navigation tabs */\n | \"toc\" /* Table of contents */\n\n/**\n * A 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 * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the element for a given component or throw a reference error\n *\n * @template T - Element type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getComponentElement(\n type: ComponentType, node: ParentNode = document\n): T {\n return getElementOrThrow(`[data-md-component=${type}]`, node)\n}\n\n/**\n * Retrieve all elements for a given component\n *\n * @template T - Element type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getComponentElements(\n type: ComponentType, node: ParentNode = document\n): T[] {\n return getElements(`[data-md-component=${type}]`, node)\n}\n","/*\n * Copyright (c) 2016-2021 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 {\n SearchDocument,\n SearchMetadata,\n SearchResult\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 .map(key => [{key}, \" \"])\n .flat()\n .slice(0, -1)\n\n /* Render article or section, depending on flags */\n const url = document.location\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 {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 renderSearchResult(\n result: SearchResult\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-2021 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 * Set anchor state\n *\n * @param el - Anchor element\n * @param state - Anchor state\n */\nexport function setAnchorState(\n el: HTMLElement, state: \"blur\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset anchor state\n *\n * @param el - Anchor element\n */\nexport function resetAnchorState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Set anchor active\n *\n * @param el - Anchor element\n * @param value - Whether the anchor is active\n */\nexport function setAnchorActive(\n el: HTMLElement, value: boolean\n): void {\n el.classList.toggle(\"md-nav__link--active\", value)\n}\n\n/**\n * Reset anchor active\n *\n * @param el - Anchor element\n */\nexport function resetAnchorActive(\n el: HTMLElement\n): void {\n el.classList.remove(\"md-nav__link--active\")\n}\n","/*\n * Copyright (c) 2016-2021 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 * @param tag - HTML tag\n * @param attributes - HTML attributes\n * @param children - Child elements\n *\n * @returns Element\n */\nexport function h(\n tag: string, attributes: Attributes | null, ...children: Child[]\n): HTMLElement {\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\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-2021 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/**\n * Simple hash function\n *\n * @see https://bit.ly/2wsVjJ4 - Original source\n *\n * @param value - Value to be hashed\n *\n * @returns Hash as 32bit integer\n */\nexport function hash(value: string): number {\n let h = 0\n for (let i = 0, len = value.length; i < len; i++) {\n h = ((h << 5) - h) + value.charCodeAt(i)\n h |= 0 // Convert to 32bit integer\n }\n return h\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set tabs state\n *\n * @param el - Tabs element\n * @param state - Tabs state\n */\nexport function setTabsState(\n el: HTMLElement, state: \"hidden\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset tabs state\n *\n * @param el - Tabs element\n */\nexport function resetTabsState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2021 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 { Observable, Subject } from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n finalize,\n map,\n tap,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport { resetFocusable, setFocusable } from \"~/actions\"\nimport {\n Viewport,\n getElementContentSize,\n getElementSize,\n watchMedia\n} from \"~/browser\"\nimport { renderClipboardButton } from \"~/templates\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Code block\n */\nexport interface CodeBlock {\n scroll: boolean /* Code block overflows */\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}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Global index for Clipboard.js integration\n */\nlet index = 0\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch code block\n *\n * @param el - Code block element\n * @param options - Options\n *\n * @returns Code block observable\n */\nexport function watchCodeBlock(\n el: HTMLElement, { viewport$ }: WatchOptions\n): Observable {\n return viewport$\n .pipe(\n distinctUntilKeyChanged(\"size\"),\n map(() => {\n const visible = getElementSize(el)\n const content = getElementContentSize(el)\n return {\n scroll: content.width > visible.width\n }\n }),\n distinctUntilKeyChanged(\"scroll\")\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 *\n * @param el - Code block element\n * @param options - Options\n *\n * @returns Code block component observable\n */\nexport function mountCodeBlock(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const internal$ = new Subject()\n internal$\n .pipe(\n withLatestFrom(watchMedia(\"(hover)\"))\n )\n .subscribe(([{ scroll }, hover]) => {\n if (scroll && hover)\n setFocusable(el)\n else\n resetFocusable(el)\n })\n\n /* Inject button for Clipboard.js integration */\n if (ClipboardJS.isSupported()) {\n const parent = el.closest(\"pre\")!\n parent.id = `__code_${index++}`\n parent.insertBefore(\n renderClipboardButton(parent.id),\n el\n )\n }\n\n /* Create and return component */\n return watchCodeBlock(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set focusable property\n *\n * @param el - Element\n * @param value - Tabindex value\n */\nexport function setFocusable(\n el: HTMLElement, value = 0\n): void {\n el.setAttribute(\"tabindex\", value.toString())\n}\n\n/**\n * Reset focusable property\n *\n * @param el - Element\n */\nexport function resetFocusable(\n el: HTMLElement\n): void {\n el.removeAttribute(\"tabindex\")\n}\n\n/**\n * Set scroll lock\n *\n * @param el - Scrollable element\n * @param value - Vertical offset\n */\nexport function setScrollLock(\n el: HTMLElement, value: number\n): void {\n el.setAttribute(\"data-md-state\", \"lock\")\n el.style.top = `-${value}px`\n}\n\n/**\n * Reset scroll lock\n *\n * @param el - Scrollable element\n */\nexport function resetScrollLock(\n el: HTMLElement\n): void {\n const value = -1 * parseInt(el.style.top, 10)\n el.removeAttribute(\"data-md-state\")\n el.style.top = \"\"\n if (value)\n window.scrollTo(0, value)\n}\n","/*\n * Copyright (c) 2016-2021 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-2021 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, Subject } from \"rxjs\"\nimport {\n filter,\n finalize,\n map,\n mapTo,\n mergeWith,\n tap\n} from \"rxjs/operators\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Details\n */\nexport interface Details {}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Print observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* 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 return target$\n .pipe(\n map(target => target.closest(\"details:not([open])\")!),\n filter(details => el === details),\n mergeWith(print$),\n mapTo(el)\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 const internal$ = new Subject
    ()\n internal$.subscribe(() => {\n el.setAttribute(\"open\", \"\")\n el.scrollIntoView()\n })\n\n /* Create and return component */\n return watchDetails(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n mapTo({ ref: el })\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { createElement, replaceElement } from \"~/browser\"\nimport { renderTable } from \"~/templates\"\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 = createElement(\"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 they\n * can be 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 replaceElement(el, sentinel)\n replaceElement(sentinel, renderTable(el))\n\n /* Create and return component */\n return of({ ref: el })\n}\n","/*\n * Copyright (c) 2016-2021 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-2021 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 merge,\n of\n} from \"rxjs\"\nimport {\n delay,\n finalize,\n map,\n observeOn,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport {\n resetDialogState,\n setDialogMessage,\n setDialogState\n} from \"~/actions\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Dialog\n */\nexport interface Dialog {\n message: string /* Dialog message */\n open: boolean /* Dialog is visible */\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(open => ({ message, open }))\n )\n )\n )\n}\n\n/**\n * Mount dialog\n *\n * This function makes the dialog in the right corner appear when a new alert\n * is 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 internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler)\n )\n .subscribe(({ message, open }) => {\n setDialogMessage(el, message)\n if (open)\n setDialogState(el, \"open\")\n else\n resetDialogState(el)\n })\n\n /* Create and return component */\n return watchDialog(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set dialog message\n *\n * @param el - Dialog element\n * @param value - Dialog message\n */\nexport function setDialogMessage(\n el: HTMLElement, value: string\n): void {\n el.firstElementChild!.innerHTML = value\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Set dialog state\n *\n * @param el - Dialog element\n * @param state - Dialog state\n */\nexport function setDialogState(\n el: HTMLElement, state: \"open\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset dialog state\n *\n * @param el - Dialog element\n */\nexport function resetDialogState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2021 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 combineLatest,\n defer,\n of\n} from \"rxjs\"\nimport {\n bufferCount,\n combineLatestWith,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n observeOn,\n shareReplay,\n startWith,\n switchMap\n} from \"rxjs/operators\"\n\nimport { feature } from \"~/_\"\nimport { resetHeaderState, setHeaderState } from \"~/actions\"\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 sticky: boolean /* Header stickyness */\n hidden: boolean /* User scrolled past threshold */\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 autohiding */\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(() => {\n const styles = getComputedStyle(el)\n return of(\n styles.position === \"sticky\" ||\n styles.position === \"-webkit-sticky\"\n )\n })\n .pipe(\n combineLatestWith(watchElementSize(el), isHidden(options)),\n map(([sticky, { height }, hidden]) => ({\n height: sticky ? height : 0,\n sticky,\n hidden\n })),\n distinctUntilChanged((a, b) => (\n a.sticky === b.sticky &&\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 const internal$ = new Subject
    ()\n internal$\n .pipe(\n distinctUntilKeyChanged(\"active\"),\n combineLatestWith(header$),\n observeOn(animationFrameScheduler)\n )\n .subscribe(([{ active }, { hidden }]) => {\n if (active)\n setHeaderState(el, hidden ? \"hidden\" : \"shadow\")\n else\n resetHeaderState(el)\n })\n\n /* Connect to long-living subject and return component */\n main$.subscribe(main => internal$.next(main))\n return header$\n .pipe(\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 animationFrameScheduler\n} from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n finalize,\n map,\n observeOn,\n tap\n} from \"rxjs/operators\"\n\nimport {\n resetHeaderTitleState,\n setHeaderTitleState\n} from \"~/actions\"\nimport {\n Viewport,\n getElement,\n getElementSize,\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 /* User scrolled past first headline */\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: HTMLHeadingElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchViewportAt(el, { header$, viewport$ })\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 const internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n )\n .subscribe(({ active }) => {\n if (active)\n setHeaderTitleState(el, \"active\")\n else\n resetHeaderTitleState(el)\n })\n\n /* Obtain headline, if any */\n const headline = getElement(\"article h1\")\n if (typeof headline === \"undefined\")\n return NEVER\n\n /* Create and return component */\n return watchHeaderTitle(headline, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set header title state\n *\n * @param el - Header title element\n * @param state - Header title state\n */\nexport function setHeaderTitleState(\n el: HTMLElement, state: \"active\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset header title state\n *\n * @param el - Header title element\n */\nexport function resetHeaderTitleState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2021 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 * A 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 * A message indicating the search index is ready\n */\nexport interface SearchReadyMessage {\n type: SearchMessageType.READY /* Message type */\n}\n\n/**\n * A message containing a search query\n */\nexport interface SearchQueryMessage {\n type: SearchMessageType.QUERY /* Message type */\n data: string /* Message data */\n}\n\n/**\n * A 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 * A 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-2021 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` 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-2021 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 { ObservableInput, Subject, from } from \"rxjs\"\nimport { map, share } from \"rxjs/operators\"\n\nimport { configuration, translation } from \"~/_\"\nimport { WorkerHandler, watchWorker } from \"~/browser\"\n\nimport { SearchIndex, SearchIndexPipeline } from \"../../_\"\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(\n { config, docs, index }: SearchIndex\n): 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 SearchIndexPipeline\n\n /* Return search index after defaulting */\n return { config, docs, index, pipeline }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search worker\n *\n * This function will create a web worker to set up and query the search index\n * which is done using `lunr`. 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)\n for (const document of result)\n document.location = `${config.base}/${document.location}`\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 }))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Return search worker */\n return { tx$, rx$ }\n}\n","/*\n * Copyright (c) 2016-2021 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, Subject, fromEvent } from \"rxjs\"\nimport {\n map,\n share,\n switchMapTo,\n tap,\n throttle\n} from \"rxjs/operators\"\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 switchMapTo(rx$),\n share()\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 fromEvent,\n merge\n} from \"rxjs\"\nimport {\n delay,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n startWith,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs/operators\"\n\nimport {\n resetSearchQueryPlaceholder,\n setSearchQueryPlaceholder\n} from \"~/actions\"\nimport {\n setElementFocus,\n setToggle,\n watchElementFocus\n} from \"~/browser\"\nimport {\n SearchMessageType,\n SearchQueryMessage,\n SearchWorker,\n defaultTransform\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 *\n * @returns Search query observable\n */\nexport function watchSearchQuery(\n el: HTMLInputElement\n): Observable {\n const fn = __search?.transform || defaultTransform\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 )\n .pipe(\n map(() => fn(el.value)),\n startWith(fn(el.value)),\n distinctUntilChanged()\n )\n\n /* Combine into single observable */\n return combineLatest([value$, focus$])\n .pipe(\n map(([value, focus]) => ({ value, focus }))\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$ }: SearchWorker\n): Observable> {\n const internal$ = new Subject()\n\n /* Handle value changes */\n internal$\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 internal$\n .pipe(\n distinctUntilKeyChanged(\"focus\")\n )\n .subscribe(({ focus }) => {\n if (focus) {\n setToggle(\"search\", focus)\n setSearchQueryPlaceholder(el, \"\")\n } else {\n resetSearchQueryPlaceholder(el)\n }\n })\n\n /* Handle reset */\n fromEvent(el.form!, \"reset\")\n .pipe(\n takeUntil(internal$.pipe(takeLast(1)))\n )\n .subscribe(() => setElementFocus(el))\n\n /* Create and return component */\n return watchSearchQuery(el)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 \"~/_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set search query placeholder\n *\n * @param el - Search query element\n * @param value - Placeholder\n */\nexport function setSearchQueryPlaceholder(\n el: HTMLInputElement, value: string\n): void {\n el.placeholder = value\n}\n\n/**\n * Reset search query placeholder\n *\n * @param el - Search query element\n */\nexport function resetSearchQueryPlaceholder(\n el: HTMLInputElement\n): void {\n el.placeholder = translation(\"search.placeholder\")\n}\n","/*\n * Copyright (c) 2016-2021 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 merge,\n of\n} from \"rxjs\"\nimport {\n bufferCount,\n filter,\n finalize,\n map,\n observeOn,\n startWith,\n switchMap,\n tap,\n withLatestFrom,\n zipWith\n} from \"rxjs/operators\"\n\nimport {\n addToSearchResultList,\n resetSearchResultList,\n resetSearchResultMeta,\n setSearchResultMeta\n} from \"~/actions\"\nimport {\n getElementOrThrow,\n watchElementThreshold\n} from \"~/browser\"\nimport {\n SearchResult as SearchResultData,\n SearchWorker,\n isSearchResultMessage\n} from \"~/integrations\"\nimport { renderSearchResult } from \"~/templates\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search result\n */\nexport interface SearchResult {\n data: SearchResultData[] /* Search result data */\n}\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 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 mountSearchResult(\n el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions\n): Observable> {\n const internal$ = new Subject()\n const boundary$ = watchElementThreshold(el.parentElement!)\n .pipe(\n filter(Boolean)\n )\n\n /* Update search result metadata */\n const meta = getElementOrThrow(\":scope > :first-child\", el)\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n withLatestFrom(query$)\n )\n .subscribe(([{ data }, { value }]) => {\n if (value)\n setSearchResultMeta(meta, data.length)\n else\n resetSearchResultMeta(meta)\n })\n\n /* Update search result list */\n const list = getElementOrThrow(\":scope > :last-child\", el)\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n tap(() => resetSearchResultList(list)),\n switchMap(({ data }) => merge(\n of(...data.slice(0, 10)),\n of(...data.slice(10))\n .pipe(\n bufferCount(4),\n zipWith(boundary$),\n switchMap(([chunk]) => of(...chunk))\n )\n ))\n )\n .subscribe(result => {\n addToSearchResultList(list, renderSearchResult(result))\n })\n\n /* Filter search result list */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => ({ data })),\n startWith({ data: [] })\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { round } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set number of search results\n *\n * @param el - Search result metadata element\n * @param value - Number of results\n */\nexport function setSearchResultMeta(\n el: HTMLElement, value: number\n): void {\n switch (value) {\n\n /* No results */\n case 0:\n el.textContent = translation(\"search.result.none\")\n break\n\n /* One result */\n case 1:\n el.textContent = translation(\"search.result.one\")\n break\n\n /* Multiple result */\n default:\n el.textContent = translation(\"search.result.other\", round(value))\n }\n}\n\n/**\n * Reset number of search results\n *\n * @param el - Search result metadata element\n */\nexport function resetSearchResultMeta(\n el: HTMLElement\n): void {\n el.textContent = translation(\"search.result.placeholder\")\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Add an element to the search result list\n *\n * @param el - Search result list element\n * @param child - Search result element\n */\nexport function addToSearchResultList(\n el: HTMLElement, child: Element\n): void {\n el.appendChild(child)\n}\n\n/**\n * Reset search result list\n *\n * @param el - Search result list element\n */\nexport function resetSearchResultList(\n el: HTMLElement\n): void {\n el.innerHTML = \"\"\n}\n","/*\n * Copyright (c) 2016-2021 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 { NEVER, Observable, ObservableInput, merge } from \"rxjs\"\nimport { filter, sample, take } from \"rxjs/operators\"\n\nimport { configuration } from \"~/_\"\nimport {\n Keyboard,\n getActiveElement,\n getElements,\n requestJSON,\n setElementFocus,\n setElementSelection,\n setToggle\n} from \"~/browser\"\nimport {\n SearchIndex,\n isSearchQueryMessage,\n isSearchReadyMessage,\n setupSearchWorker\n} from \"~/integrations\"\n\nimport { Component, getComponentElement } from \"../../_\"\nimport { SearchQuery, mountSearchQuery } from \"../query\"\nimport { SearchResult, mountSearchResult } from \"../result\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search\n */\nexport type Search =\n | SearchQuery\n | SearchResult\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @param url - Search index URL\n *\n * @returns Promise or observable\n */\nfunction fetchSearchIndex(url: string): ObservableInput {\n return __search?.index || requestJSON(url)\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, { keyboard$ }: MountOptions\n): Observable> {\n if (location.protocol === \"file:\")\n return NEVER\n\n /* Set up search worker */\n const config = configuration()\n const worker = setupSearchWorker(config.search, fetchSearchIndex(\n `${config.base}/search/search_index.json`\n ))\n\n /* Retrieve nested 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: prevent form submission */\n case \"Enter\":\n if (active === query)\n key.claim()\n break\n\n /* Escape or Tab: close search */\n case \"Escape\":\n case \"Tab\":\n setToggle(\"search\", false)\n setElementFocus(query, false)\n break\n\n /* Vertical arrows: select previous or next search result */\n case \"ArrowUp\":\n case \"ArrowDown\":\n if (typeof active === \"undefined\") {\n setElementFocus(query)\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 setElementFocus(els[i])\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 setElementFocus(query)\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 setElementFocus(query)\n setElementSelection(query)\n key.claim()\n break\n }\n })\n\n /* Create and return component */\n const query$ = mountSearchQuery(query as HTMLInputElement, worker)\n return merge(\n query$,\n mountSearchResult(result, worker, { query$ })\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set element text selection\n *\n * @param el - Element\n */\nexport function setElementSelection(\n el: HTMLElement\n): void {\n if (el instanceof HTMLInputElement)\n el.select()\n else\n throw new Error(\"Not implemented\")\n}\n","/*\n * Copyright (c) 2016-2021 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 combineLatest\n} from \"rxjs\"\nimport {\n distinctUntilChanged,\n finalize,\n map,\n observeOn,\n tap,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport {\n resetSidebarHeight,\n resetSidebarOffset,\n setSidebarHeight,\n setSidebarOffset\n} from \"~/actions\"\nimport { Viewport } 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 /* User scrolled past header */\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 adjust =\n el.parentElement!.offsetTop -\n el.parentElement!.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 * @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 internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n withLatestFrom(header$)\n )\n .subscribe({\n\n /* Update height and offset */\n next([{ height }, { height: offset }]) {\n setSidebarHeight(el, height)\n setSidebarOffset(el, offset)\n },\n\n /* Reset on complete */\n complete() {\n resetSidebarOffset(el)\n resetSidebarHeight(el)\n }\n })\n\n /* Create and return component */\n return watchSidebar(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set sidebar offset\n *\n * @param el - Sidebar element\n * @param value - Sidebar offset\n */\nexport function setSidebarOffset(\n el: HTMLElement, value: number\n): void {\n el.style.top = `${value}px`\n}\n\n/**\n * Reset sidebar offset\n *\n * @param el - Sidebar element\n */\nexport function resetSidebarOffset(\n el: HTMLElement\n): void {\n el.style.top = \"\"\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Set sidebar height\n *\n * This function doesn't set the height of the actual sidebar, but of its first\n * child – 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 value - Sidebar height\n */\nexport function setSidebarHeight(\n el: HTMLElement, value: number\n): void {\n const scrollwrap = el.firstElementChild as HTMLElement\n scrollwrap.style.height = `${value - 2 * scrollwrap.offsetTop}px`\n}\n\n/**\n * Reset sidebar height\n *\n * @param el - Sidebar element\n */\nexport function resetSidebarHeight(\n el: HTMLElement\n): void {\n const scrollwrap = el.firstElementChild as HTMLElement\n scrollwrap.style.height = \"\"\n}\n","/*\n * Copyright (c) 2016-2021 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 { NEVER, Observable } from \"rxjs\"\n\nimport { fetchSourceFactsFromGitHub } from \"../github\"\nimport { fetchSourceFactsFromGitLab } from \"../gitlab\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository facts\n */\nexport type SourceFacts = string[]\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 NEVER\n }\n}\n","/*\n * Copyright (c) 2016-2021 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 { Observable } from \"rxjs\"\nimport { defaultIfEmpty, map } from \"rxjs/operators\"\n\nimport { requestJSON } from \"~/browser\"\nimport { round } from \"~/utilities\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitHub repository facts\n *\n * @param user - GitHub user\n * @param repo - GitHub repository\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitHub(\n user: string, repo?: string\n): Observable {\n const url = typeof repo !== \"undefined\"\n ? `https://api.github.com/repos/${user}/${repo}`\n : `https://api.github.com/users/${user}`\n return requestJSON(url)\n .pipe(\n map(data => {\n\n /* GitHub repository */\n if (typeof repo !== \"undefined\") {\n const { stargazers_count, forks_count }: Repo = data\n return [\n `${round(stargazers_count!)} Stars`,\n `${round(forks_count!)} Forks`\n ]\n\n /* GitHub user/organization */\n } else {\n const { public_repos }: User = data\n return [\n `${round(public_repos!)} Repositories`\n ]\n }\n }),\n defaultIfEmpty([])\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { Observable } from \"rxjs\"\nimport { defaultIfEmpty, map } from \"rxjs/operators\"\n\nimport { requestJSON } from \"~/browser\"\nimport { round } from \"~/utilities\"\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 `${round(star_count)} Stars`,\n `${round(forks_count)} Forks`\n ])),\n defaultIfEmpty([])\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { NEVER, Observable, Subject, defer, of } from \"rxjs\"\nimport {\n catchError,\n filter,\n finalize,\n map,\n shareReplay,\n tap\n} from \"rxjs/operators\"\n\nimport { setSourceFacts, setSourceState } from \"~/actions\"\nimport { renderSourceFacts } from \"~/templates\"\nimport { hash } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\nimport { SourceFacts, fetchSourceFacts } 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 facts observable\n */\nlet fetch$: Observable\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch repository information\n *\n * This function will try to read the repository facts from session storage,\n * and if unsuccessful, fetch 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 const digest = hash(el.href).toString()\n\n /* Fetch repository facts once */\n return fetch$ ||= defer(() => {\n const data = sessionStorage.getItem(digest)\n if (data) {\n return of(JSON.parse(data))\n } else {\n const value$ = fetchSourceFacts(el.href)\n value$.subscribe(value => {\n try {\n sessionStorage.setItem(digest, JSON.stringify(value))\n } catch (err) {\n /* Uncritical, just swallow */\n }\n })\n\n /* Return value */\n return value$\n }\n })\n .pipe(\n catchError(() => NEVER),\n filter(facts => 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 internal$ = new Subject()\n internal$.subscribe(({ facts }) => {\n setSourceFacts(el, renderSourceFacts(facts))\n setSourceState(el, \"done\")\n })\n\n /* Create and return component */\n return watchSource(el)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set repository facts\n *\n * @param el - Repository element\n * @param child - Repository facts element\n */\nexport function setSourceFacts(\n el: HTMLElement, child: Element\n): void {\n el.lastElementChild!.appendChild(child)\n}\n\n/**\n * Set repository state\n *\n * @param el - Repository element\n * @param state - Repository state\n */\nexport function setSourceState(\n el: HTMLElement, state: \"done\"\n): void {\n el.lastElementChild!.setAttribute(\"data-md-state\", state)\n}\n","/*\n * Copyright (c) 2016-2021 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 } 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 {facts.map(fact => (\n
    • {fact}
    • \n ))}\n
    \n )\n}\n","/*\n * Copyright (c) 2016-2021 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, Subject, animationFrameScheduler } from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n finalize,\n map,\n observeOn,\n tap\n} from \"rxjs/operators\"\n\nimport { resetTabsState, setTabsState } from \"~/actions\"\nimport { Viewport, watchViewportAt } 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 /* User scrolled past tabs */\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 watchViewportAt(el, { header$, viewport$ })\n .pipe(\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 const internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler)\n )\n .subscribe({\n\n /* Update state */\n next({ hidden }) {\n if (hidden)\n setTabsState(el, \"hidden\")\n else\n resetTabsState(el)\n },\n\n /* Reset on complete */\n complete() {\n resetTabsState(el)\n }\n })\n\n /* Create and return component */\n return watchTabs(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 combineLatest\n} from \"rxjs\"\nimport {\n bufferCount,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n observeOn,\n scan,\n startWith,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport {\n resetAnchorActive,\n resetAnchorState,\n setAnchorActive,\n setAnchorState\n} from \"~/actions\"\nimport {\n Viewport,\n getElement,\n getElements,\n watchElementSize\n} from \"~/browser\"\n\nimport { Component } 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}\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 anchors - Anchor elements\n * @param options - Options\n *\n * @returns Table of contents observable\n */\nexport function watchTableOfContents(\n anchors: HTMLAnchorElement[], { viewport$, header$ }: WatchOptions\n): Observable {\n const table = new Map()\n for (const anchor of anchors) {\n const id = decodeURIComponent(anchor.hash.substring(1))\n const target = getElement(`[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 map(header => 24 + header.height)\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 map(() => {\n let path: HTMLAnchorElement[] = []\n return [...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\n /* Re-compute partition when viewport offset changes */\n switchMap(index => combineLatest([adjust$, viewport$])\n .pipe(\n scan(([prev, next], [adjust, { offset: { y } }]) => {\n\n /* Look forward */\n while (next.length) {\n const [, offset] = next[0]\n if (offset - adjust < y) {\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) {\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 /* 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 - Anchor list element\n * @param options - Options\n *\n * @returns Table of contents component observable\n */\nexport function mountTableOfContents(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n )\n .subscribe(({ prev, next }) => {\n\n /* Look forward */\n for (const [anchor] of next) {\n resetAnchorActive(anchor)\n resetAnchorState(anchor)\n }\n\n /* Look backward */\n for (const [index, [anchor]] of prev.entries()) {\n setAnchorActive(anchor, index === prev.length - 1)\n setAnchorState(anchor, \"blur\")\n }\n })\n\n /* Create and return component */\n const anchors = getElements(\"[href^=\\\\#]\", el)\n return watchTableOfContents(anchors, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent, of } from \"rxjs\"\nimport {\n filter,\n mapTo,\n mergeMap,\n switchMap,\n tap\n} from \"rxjs/operators\"\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(() => of(...getElements(\"[data-md-scrollfix]\"))),\n tap(el => el.removeAttribute(\"data-md-scrollfix\")),\n filter(isAppleDevice),\n mergeMap(el => fromEvent(el, \"touchstart\")\n .pipe(\n mapTo(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-2021 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 \"focus-visible\"\nimport { Subject, defer, merge } from \"rxjs\"\nimport {\n filter,\n map,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs/operators\"\n\nimport { feature } from \"./_\"\nimport {\n at,\n getElement,\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 mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountSearch,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n setupClipboardJS,\n setupInstantLoading\n} from \"./integrations\"\nimport {\n patchIndeterminate,\n patchScrollfix\n} from \"./patches\"\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 */\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/* 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/* Always close drawer on navigation */\nmerge(location$, target$)\n .subscribe(() => setToggle(\"drawer\", false))\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 = getElement(\"[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 = getElement(\"[href][rel=next]\")\n if (typeof next !== \"undefined\")\n next.click()\n break\n }\n })\n\n/* Set up patches */\npatchIndeterminate({ document$ })\npatchScrollfix({ document$ })\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 /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el as HTMLAnchorElement)),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { target$, viewport$, print$ })),\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 /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, { viewport$, header$ })),\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/* Export to window */\nexport {\n document$,\n location$,\n target$,\n keyboard$,\n viewport$,\n tablet$,\n screen$,\n print$,\n component$\n}\n","/*\n * Copyright (c) 2016-2021 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 { ReplaySubject, Subject, fromEvent } from \"rxjs\"\nimport { mapTo } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch document\n *\n * Documents must be implemented as subjects, so all downstream observables are\n * automatically updated when a new document is emitted. This enabled features\n * like instant loading.\n *\n * @returns Document subject\n */\nexport function watchDocument(): Subject {\n const document$ = new ReplaySubject()\n fromEvent(document, \"DOMContentLoaded\")\n .pipe(\n mapTo(document)\n )\n .subscribe(document$)\n\n /* Return document */\n return document$\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent } from \"rxjs\"\nimport { filter, map, share } from \"rxjs/operators\"\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 *\n * @returns Test result\n */\nfunction isSusceptibleToKeyboard(el: HTMLElement): boolean {\n switch (el.tagName) {\n\n /* Form elements */\n case \"INPUT\":\n case \"SELECT\":\n case \"TEXTAREA\":\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 }) => {\n if (mode === \"global\") {\n const active = getActiveElement()\n if (typeof active !== \"undefined\")\n return !isSusceptibleToKeyboard(active)\n }\n return true\n }),\n share()\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { Observable, Subject } from \"rxjs\"\n\nimport { translation } from \"~/_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n alert$: Subject /* Alert subject */\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 .on(\"success\", ev => subscriber.next(ev))\n })\n .subscribe(() => alert$.next(translation(\"clipboard.copied\")))\n }\n}\n","/*\n * Copyright (c) 2016-2021 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 fromEvent,\n merge,\n of\n} from \"rxjs\"\nimport {\n bufferCount,\n catchError,\n concatMap,\n debounceTime,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n sample,\n share,\n skip,\n skipUntil,\n switchMap\n} from \"rxjs/operators\"\n\nimport { configuration } from \"~/_\"\nimport {\n Viewport,\n ViewportOffset,\n createElement,\n getElement,\n getElements,\n replaceElement,\n request,\n requestXML,\n setLocation,\n setLocationHash,\n setViewportOffset\n} from \"~/browser\"\nimport { getComponentElement } from \"~/components\"\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 * 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 Processed URLs\n */\nfunction preprocess(urls: string[]): string[] {\n if (urls.length < 2)\n return urls\n\n /* Compute references URLs */\n const [root, next] = urls.sort((a, b) => a.length - b.length)\n\n /* Compute common prefix */\n let index = 0\n if (root === next)\n index = root.length\n else\n while (root.charCodeAt(index) === root.charCodeAt(index))\n index++\n\n /* Replace common prefix (i.e. base) with effective base */\n const config = configuration()\n return urls.map(url => (\n url.replace(root.slice(0, index), `${config.base}/`)\n ))\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 = getElement(\"link[rel='shortcut icon']\")\n if (typeof favicon !== \"undefined\")\n favicon.href = favicon.href\n\n /* Intercept internal navigation */\n const push$ = requestXML(`${config.base}/sitemap.xml`)\n .pipe(\n map(sitemap => preprocess(getElements(\"loc\", sitemap)\n .map(node => node.textContent!)\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 HTMLElement) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target && urls.includes(el.href)) {\n ev.preventDefault()\n return of({\n url: new URL(el.href)\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 skip(1),\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.toString())\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 /* 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 setViewportOffset(offset || { y: 0 })\n })\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=header-title]\",\n \"[data-md-component=container]\",\n \"[data-md-component=skip]\"\n ]) {\n const source = getElement(selector)\n const target = getElement(selector, replacement)\n if (\n typeof source !== \"undefined\" &&\n typeof target !== \"undefined\"\n ) {\n replaceElement(source, target)\n }\n }\n })\n\n /* Re-evaluate scripts */\n document$\n .pipe(\n skip(1),\n map(() => getComponentElement(\"container\")),\n switchMap(el => of(...getElements(\"script\", el))),\n concatMap(el => {\n const script = createElement(\"script\")\n if (el.src) {\n script.src = el.src\n replaceElement(el, 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 replaceElement(el, script)\n return EMPTY\n }\n })\n )\n .subscribe()\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 setViewportOffset(offset || { y: 0 })\n })\n}\n","/*\n * Copyright (c) 2016-2021 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 } 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 * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch indeterminate checkboxes\n *\n * This function will replace 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$ }: PatchOptions\n): void {\n document$.subscribe(() => {\n for (const el of getElements(\n \"[data-md-state=indeterminate]\"\n )) {\n el.setAttribute(\"data-md-state\", \"\")\n el.indeterminate = true\n el.checked = false\n }\n })\n}\n","/*\n * Copyright (c) 2016-2021 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} from \"rxjs\"\nimport {\n distinctUntilChanged,\n distinctUntilKeyChanged,\n map,\n switchMap\n} from \"rxjs/operators\"\n\nimport { Viewport, watchElementSize } 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 /* User scrolled past header */\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-2021 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 * Set header state\n *\n * @param el - Header element\n * @param state - Header state\n */\nexport function setHeaderState(\n el: HTMLElement, state: \"shadow\" | \"hidden\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset header state\n *\n * @param el - Header element\n */\nexport function resetHeaderState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2021 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 { Viewport, getElements } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { CodeBlock, mountCodeBlock } from \"../code\"\nimport { Details, mountDetails } from \"../details\"\nimport { DataTable, mountDataTable } from \"../table\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content\n */\nexport type Content =\n | CodeBlock\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 viewport$: Observable /* Viewport observable */\n print$: Observable /* 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$, viewport$, print$ }: MountOptions\n): Observable> {\n return merge(\n\n /* Code blocks */\n ...getElements(\"pre > code\", el)\n .map(child => mountCodeBlock(child, { viewport$ })),\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}\n"],"sourceRoot":""} \ No newline at end of file diff --git a/material/assets/javascripts/bundle.9a5a6e7c.min.js b/material/assets/javascripts/bundle.9a5a6e7c.min.js new file mode 100644 index 000000000..7259d7b3b --- /dev/null +++ b/material/assets/javascripts/bundle.9a5a6e7c.min.js @@ -0,0 +1,2 @@ +!function(e,t){for(var c in t)e[c]=t[c]}(window,function(e){function t(t){for(var n,o,i=t[0],s=t[1],b=t[2],u=0,l=[];uObject(y.a)(new ResizeObserver(e=>{for(const t of e)k.next(t)}))).pipe(Object(s.a)(e=>x.a.pipe(Object(v.a)(e)).pipe(Object(_.a)(()=>e.disconnect()))),Object(b.a)(1));function T(e){return{width:e.offsetWidth,height:e.offsetHeight}}function S(e){return{width:e.scrollWidth,height:e.scrollHeight}}function R(e){return A.pipe(Object(E.a)(t=>t.observe(e)),Object(s.a)(t=>k.pipe(Object(o.a)(({target:t})=>t===e),Object(_.a)(()=>t.unobserve(e)),Object(i.a)(({contentRect:e})=>({width:e.width,height:e.height})))),Object(v.a)(T(e)))}function M(e){return{x:e.scrollLeft,y:e.scrollTop}}function C(e,t=16){return function(e){return Object(a.a)(Object(l.a)(e,"scroll"),Object(l.a)(window,"resize")).pipe(Object(i.a)(()=>M(e)),Object(v.a)(M(e)))}(e).pipe(Object(i.a)(({y:c})=>{const n=T(e);return c>=S(e).height-n.height-t}),Object($.a)())}var L=c(42);const P={drawer:O("[data-md-toggle=drawer]"),search:O("[data-md-toggle=search]")};function U(e,t){P[e].checked!==t&&P[e].click()}var N=c(60);function H(){return new URL(location.href)}function z(){return location.hash.substring(1)}function I(e){const t=matchMedia(e);return Object(l.a)(t,"change").pipe(Object(i.a)(e=>e.matches),Object(v.a)(t.matches))}function D(e,t){return e.pipe(Object(s.a)(e=>e?t():x.a))}var Y=c(6);function F(e,t={credentials:"same-origin"}){return Object(Y.a)(fetch(e,t)).pipe(Object(o.a)(e=>200===e.status))}function q(e,t){return F(e,t).pipe(Object(s.a)(e=>e.json()),Object(b.a)(1))}var J=c(46),W=c(61);function B(){return{x:Math.max(0,pageXOffset),y:Math.max(0,pageYOffset)}}function K({x:e,y:t}){window.scrollTo(e||0,t||0)}function Q(){return{width:innerWidth,height:innerHeight}}function X(e,{viewport$:t,header$:c}){const n=t.pipe(Object(W.a)("size")),a=Object(J.a)([n,c]).pipe(Object(i.a)(()=>({x:e.offsetLeft,y:e.offsetTop})));return Object(J.a)([c,t,a]).pipe(Object(i.a)(([{height:e},{offset:t,size:c},{x:n,y:a}])=>({offset:{x:t.x-n,y:t.y-a+e},size:c})))}var V=c(62),G=c(63);const Z=O("#__config"),ee=JSON.parse(Z.textContent);function te(){return ee}function ce(e){return ee.features.includes(e)}function ne(e,t){return void 0!==t?ee.translations[e].replace("#",t.toString()):ee.translations[e]}function ae(e,t=document){return O(`[data-md-component=${e}]`,t)}function re(e,t=document){return h(`[data-md-component=${e}]`,t)}ee.base=new URL(ee.base,H()).toString().replace(/\/$/,"");var oe,ie=c(26),se=c.n(ie),be=c(64);function pe(e,t){e.setAttribute("data-md-state",t)}function ue(e){e.removeAttribute("data-md-state")}function le(e,t){e.classList.toggle("md-nav__link--active",t)}function fe(e){e.classList.remove("md-nav__link--active")}function de(e,t){if("string"==typeof t||"number"==typeof t)e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(const c of t)de(e,c)}function Oe(e,t,...c){const n=document.createElement(e);if(t)for(const e of Object.keys(t))"boolean"!=typeof t[e]?n.setAttribute(e,t[e]):t[e]&&n.setAttribute(e,"");for(const e of c)de(n,e);return n}function je(e){if(e>999){return((e+1e-6)/1e3).toFixed(+((e-950)%1e3>99))+"k"}return e.toString()}function he(e){e.removeAttribute("data-md-state")}function me(e,t){const c=t&oe.PARENT,n=t&oe.TEASER,a=Object.keys(e.terms).filter(t=>!e.terms[t]).map(e=>[Oe("del",null,e)," "]).flat().slice(0,-1);return Oe("a",{href:e.location,class:"md-search-result__link",tabIndex:-1},Oe("article",{class:["md-search-result__article",...c?["md-search-result__article--document"]:[]].join(" "),"data-md-score":e.score.toFixed(2)},c>0&&Oe("div",{class:"md-search-result__icon md-icon"}),Oe("h1",{class:"md-search-result__title"},e.title),n>0&&e.text.length>0&&Oe("p",{class:"md-search-result__teaser"},function(e,t){let c=t;if(e.length>c){for(;" "!==e[c]&&--c>0;);return e.substring(0,c)+"..."}return e}(e.text,320)),n>0&&a.length>0&&Oe("p",{class:"md-search-result__terms"},ne("search.result.term.missing"),": ",a)))}!function(e){e[e.TEASER=1]="TEASER",e[e.PARENT=2]="PARENT"}(oe||(oe={}));let ge=0;function ve(e,t){const c=new n.a;if(c.pipe(Object(be.a)(I("(hover)"))).subscribe(([{scroll:t},c])=>{t&&c?function(e,t=0){e.setAttribute("tabindex",t.toString())}(e):function(e){e.removeAttribute("tabindex")}(e)}),se.a.isSupported()){const t=e.closest("pre");t.id="__code_"+ge++,t.insertBefore((r=t.id,Oe("button",{class:"md-clipboard md-icon",title:ne("clipboard.copy"),"data-clipboard-target":`#${r} > code`})),e)}var r;return function(e,{viewport$:t}){const c=Object(y.a)(e).pipe(Object(s.a)(e=>{const t=e.closest("[data-tabs]");return t instanceof HTMLElement?Object(a.a)(...h("input",t).map(e=>Object(l.a)(e,"change"))):x.a}),Object(L.a)());return Object(a.a)(t.pipe(Object(W.a)("size")),c).pipe(Object(i.a)(()=>{const t=T(e);return{scroll:S(e).width>t.width}}),Object(W.a)("scroll"))}(e,t).pipe(Object(E.a)(c),Object(_.a)(()=>c.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}function we(e,t){const c=new n.a;return c.subscribe(()=>{e.setAttribute("open",""),e.scrollIntoView()}),function(e,{target$:t,print$:c}){return t.pipe(Object(i.a)(e=>e.closest("details:not([open])")),Object(o.a)(t=>e===t),Object(p.a)(c),Object(f.a)(e))}(e,t).pipe(Object(E.a)(c),Object(_.a)(()=>c.complete()),Object(f.a)({ref:e}))}const $e=m("table");function ye(e){return g(e,$e),g($e,Oe("div",{class:"md-typeset__scrollwrap"},Oe("div",{class:"md-typeset__table"},e))),Object(y.a)({ref:e})}var xe=c(77),_e=c(78),Ee=c(66);function ke(e,t){const c=new n.a;return c.pipe(Object(Ee.a)(xe.a)).subscribe(({message:t,open:c})=>{!function(e,t){e.firstElementChild.innerHTML=t}(e,t),c?function(e,t){e.setAttribute("data-md-state",t)}(e,"open"):function(e){e.removeAttribute("data-md-state")}(e)}),function(e,{alert$:t}){return t.pipe(Object(s.a)(e=>Object(a.a)(Object(y.a)(!0),Object(y.a)(!1).pipe(Object(_e.a)(2e3))).pipe(Object(i.a)(t=>({message:e,open:t})))))}(0,t).pipe(Object(E.a)(c),Object(_.a)(()=>c.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var Ae=c(67),Te=c(68);function Se({viewport$:e}){if(!ce("header.autohide"))return Object(y.a)(!1);const t=e.pipe(Object(i.a)(({offset:{y:e}})=>e),Object(Ae.a)(2,1),Object(i.a)(([e,t])=>[eMath.abs(t-e.y)>100),Object(i.a)(([,[e]])=>e),Object($.a)()),n=function(e){const t=P[e];return Object(l.a)(t,"change").pipe(Object(i.a)(()=>t.checked),Object(v.a)(t.checked))}("search");return Object(J.a)([e,n]).pipe(Object(i.a)(([{offset:e},t])=>e.y>400&&!t),Object($.a)(),Object(s.a)(e=>e?c:Object(y.a)(!1)),Object(v.a)(!1))}function Re(e,t){const c=new n.a;c.pipe(Object(Ee.a)(xe.a)).subscribe(({active:t})=>{t?function(e,t){e.setAttribute("data-md-state",t)}(e,"active"):function(e){e.removeAttribute("data-md-state")}(e)});const a=d("article h1");return void 0===a?x.a:function(e,{viewport$:t,header$:c}){return X(e,{header$:c,viewport$:t}).pipe(Object(i.a)(({offset:{y:t}})=>{const{height:c}=T(e);return{active:t>=c}}),Object(W.a)("active"))}(a,t).pipe(Object(E.a)(c),Object(_.a)(()=>c.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var Me=c(71),Ce=c(39),Le=c(3);var Pe=c(17),Ue=c(69),Ne=c(70),He=c(72),ze=c(73),Ie=c(79);var De;c(45);function Ye(e){return e.split(/"([^"]+)"/g).map((e,t)=>1&t?e.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):e).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").trim()}function Fe(e){return e.type===De.READY}function qe(e){return e.type===De.QUERY}function Je(e){return e.type===De.RESULT}function We({config:e,docs:t,index:c}){1===e.lang.length&&"en"===e.lang[0]&&(e.lang=[ne("search.config.lang")]),"[\\s\\-]+"===e.separator&&(e.separator=ne("search.config.separator"));return{config:e,docs:t,index:c,pipeline:ne("search.config.pipeline").split(/\s*,\s*/).filter(Boolean)}}function Be(e,t){const c=te(),a=new Worker(e),r=new n.a,o=function(e,{tx$:t}){const c=Object(l.a)(e,"message").pipe(Object(i.a)(({data:e})=>e));return t.pipe(Object(V.a)(()=>c,{leading:!0,trailing:!0}),Object(E.a)(t=>e.postMessage(t)),Object(G.a)(c),Object(L.a)())}(a,{tx$:r}).pipe(Object(i.a)(e=>{if(Je(e))for(const t of e.data)for(const e of t)e.location=`${c.base}/${e.location}`;return e}),Object(L.a)());return Object(Y.a)(t).pipe(Object(i.a)(e=>({type:De.SETUP,data:We(e)}))).subscribe(r.next.bind(r)),{tx$:r,rx$:o}}!function(e){e[e.SETUP=0]="SETUP",e[e.READY=1]="READY",e[e.QUERY=2]="QUERY",e[e.RESULT=3]="RESULT"}(De||(De={}));var Ke=c(74),Qe=c(75);function Xe(e){const t=(null===__search||void 0===__search?void 0:__search.transform)||Ye,c=function(e){return Object(a.a)(Object(l.a)(e,"focus"),Object(l.a)(e,"blur")).pipe(Object(i.a)(({type:e})=>"focus"===e),Object(v.a)(e===j()))}(e),n=Object(a.a)(Object(l.a)(e,"keyup"),Object(l.a)(e,"focus").pipe(Object(_e.a)(1))).pipe(Object(i.a)(()=>t(e.value)),Object(v.a)(t(e.value)),Object($.a)());return Object(J.a)([n,c]).pipe(Object(i.a)(([e,t])=>({value:e,focus:t})))}function Ve(e,{tx$:t}){const c=new n.a;return c.pipe(Object(W.a)("value"),Object(i.a)(({value:e})=>({type:De.QUERY,data:e}))).subscribe(t.next.bind(t)),c.pipe(Object(W.a)("focus")).subscribe(({focus:t})=>{t?(U("search",t),function(e,t){e.placeholder=t}(e,"")):function(e){e.placeholder=ne("search.placeholder")}(e)}),Object(l.a)(e.form,"reset").pipe(Object(Ke.a)(c.pipe(Object(Qe.a)(1)))).subscribe(()=>w(e)),Xe(e).pipe(Object(E.a)(c),Object(_.a)(()=>c.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var Ge=c(80);function Ze(e,{rx$:t},{query$:c}){const r=new n.a,b=C(e.parentElement).pipe(Object(o.a)(Boolean)),p=O(":scope > :first-child",e);r.pipe(Object(Ee.a)(xe.a),Object(be.a)(c)).subscribe(([{data:e},{value:t}])=>{t?function(e,t){switch(t){case 0:e.textContent=ne("search.result.none");break;case 1:e.textContent=ne("search.result.one");break;default:e.textContent=ne("search.result.other",je(t))}}(p,e.length):function(e){e.textContent=ne("search.result.placeholder")}(p)});const u=O(":scope > :last-child",e);r.pipe(Object(Ee.a)(xe.a),Object(E.a)(()=>function(e){e.innerHTML=""}(u)),Object(s.a)(({data:e})=>Object(a.a)(Object(y.a)(...e.slice(0,10)),Object(y.a)(...e.slice(10)).pipe(Object(Ae.a)(4),Object(Ge.a)(b),Object(s.a)(([e])=>Object(y.a)(...e)))))).subscribe(e=>{!function(e,t){e.appendChild(t)}(u,function(e){const t=e[0].score,c=[...e],n=c.findIndex(e=>!e.location.includes("#")),[a]=c.splice(n,1);let r=c.findIndex(e=>e.scoreme(e,oe.TEASER)),...i.length?[Oe("details",{class:"md-search-result__more"},Oe("summary",{tabIndex:-1},i.length>0&&1===i.length?ne("search.result.more.one"):ne("search.result.more.other",i.length)),i.map(e=>me(e,oe.TEASER)))]:[]];return Oe("li",{class:"md-search-result__item"},s)}(e))});return t.pipe(Object(o.a)(Je),Object(i.a)(({data:e})=>({data:e})),Object(v.a)({data:[]})).pipe(Object(E.a)(r),Object(_.a)(()=>r.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}function et(e,{keyboard$:t}){if("file:"===location.protocol)return x.a;const c=te(),n=Be(c.search,(r=c.base+"/search/search_index.json",(null===__search||void 0===__search?void 0:__search.index)||q(r)));var r;const i=ae("search-query",e),s=ae("search-result",e),{tx$:b,rx$:p}=n;b.pipe(Object(o.a)(qe),Object(Me.a)(p.pipe(Object(o.a)(Fe))),Object(Ce.a)(1)).subscribe(b.next.bind(b)),t.pipe(Object(o.a)(({mode:e})=>"search"===e)).subscribe(e=>{const t=j();switch(e.type){case"Enter":t===i&&e.claim();break;case"Escape":case"Tab":U("search",!1),w(i,!1);break;case"ArrowUp":case"ArrowDown":if(void 0===t)w(i);else{const c=[i,...h(":not(details) > [href], summary, details[open] [href]",s)],n=Math.max(0,(Math.max(0,c.indexOf(t))+c.length+("ArrowUp"===e.type?-1:1))%c.length);w(c[n])}e.claim();break;default:i!==j()&&w(i)}}),t.pipe(Object(o.a)(({mode:e})=>"global"===e)).subscribe(e=>{switch(e.type){case"f":case"s":case"/":w(i),function(e){if(!(e instanceof HTMLInputElement))throw new Error("Not implemented");e.select()}(i),e.claim()}});const u=Ve(i,n);return Object(a.a)(u,Ze(s,n,{query$:u}))}var tt=c(25);function ct(e,t){var{header$:c}=t,a=Object(tt.c)(t,["header$"]);const r=new n.a;return r.pipe(Object(Ee.a)(xe.a),Object(be.a)(c)).subscribe({next([{height:t},{height:c}]){!function(e,t){const c=e.firstElementChild;c.style.height=t-2*c.offsetTop+"px"}(e,t),function(e,t){e.style.top=t+"px"}(e,c)},complete(){!function(e){e.style.top=""}(e),function(e){e.firstElementChild.style.height=""}(e)}}),function(e,{viewport$:t,main$:c}){const n=e.parentElement.offsetTop-e.parentElement.parentElement.offsetTop;return Object(J.a)([c,t]).pipe(Object(i.a)(([{offset:e,height:t},{offset:{y:c}}])=>({height:t=t+Math.min(n,Math.max(0,c-e))-n,locked:c>=e+n})),Object($.a)((e,t)=>e.height===t.height&&e.locked===t.locked))}(e,a).pipe(Object(E.a)(r),Object(_.a)(()=>r.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var nt=c(76);function at(e){const[t]=e.match(/(git(?:hub|lab))/i)||[];switch(t.toLowerCase()){case"github":const[,t,c]=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);return function(e,t){return q(void 0!==t?`https://api.github.com/repos/${e}/${t}`:"https://api.github.com/users/"+e).pipe(Object(i.a)(e=>{if(void 0!==t){const{stargazers_count:t,forks_count:c}=e;return[je(t)+" Stars",je(c)+" Forks"]}{const{public_repos:t}=e;return[je(t)+" Repositories"]}}),Object(nt.a)([]))}(t,c);case"gitlab":const[,n,a]=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i);return function(e,t){return q(`https://${e}/api/v4/projects/${encodeURIComponent(t)}`).pipe(Object(i.a)(({star_count:e,forks_count:t})=>[je(e)+" Stars",je(t)+" Forks"]),Object(nt.a)([]))}(n,a);default:return x.a}}let rt;function ot(e){const t=new n.a;return t.subscribe(({facts:t})=>{!function(e,t){e.lastElementChild.appendChild(t)}(e,function(e){return Oe("ul",{class:"md-source__facts"},e.map(e=>Oe("li",{class:"md-source__fact"},e)))}(t)),function(e,t){e.lastElementChild.setAttribute("data-md-state",t)}(e,"done")}),function(e){const t=function(e){let t=0;for(let c=0,n=e.length;c{const c=sessionStorage.getItem(t);if(c)return Object(y.a)(JSON.parse(c));{const c=at(e.href);return c.subscribe(e=>{try{sessionStorage.setItem(t,JSON.stringify(e))}catch(e){}}),c}}).pipe(Object(Ne.a)(()=>x.a),Object(o.a)(e=>e.length>0),Object(i.a)(e=>({facts:e})),Object(b.a)(1)))}(e).pipe(Object(E.a)(t),Object(_.a)(()=>t.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}function it(e,t){const c=new n.a;return c.pipe(Object(Ee.a)(xe.a)).subscribe({next({hidden:t}){t?function(e,t){e.setAttribute("data-md-state",t)}(e,"hidden"):he(e)},complete(){he(e)}}),function(e,{viewport$:t,header$:c}){return X(e,{header$:c,viewport$:t}).pipe(Object(i.a)(({offset:{y:e}})=>({hidden:e>=10})),Object(W.a)("hidden"))}(e,t).pipe(Object(E.a)(c),Object(_.a)(()=>c.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var st=c(81);function bt(e,t){const c=new n.a;c.pipe(Object(Ee.a)(xe.a)).subscribe(({prev:e,next:t})=>{for(const[e]of t)fe(e),ue(e);for(const[t,[c]]of e.entries())le(c,t===e.length-1),pe(c,"blur")});return function(e,{viewport$:t,header$:c}){const n=new Map;for(const t of e){const e=d(`[id="${decodeURIComponent(t.hash.substring(1))}"]`);void 0!==e&&n.set(t,e)}const a=c.pipe(Object(i.a)(e=>24+e.height));return R(document.body).pipe(Object(W.a)("height"),Object(i.a)(()=>{let e=[];return[...n].reduce((t,[c,a])=>{for(;e.length;){if(!(n.get(e[e.length-1]).tagName>=a.tagName))break;e.pop()}let r=a.offsetTop;for(;!r&&a.parentElement;)r=(a=a.parentElement).offsetTop;return t.set([...e=[...e,c]].reverse(),r)},new Map)}),Object(s.a)(e=>Object(J.a)([a,t]).pipe(Object(st.a)(([e,t],[c,{offset:{y:n}}])=>{for(;t.length;){const[,a]=t[0];if(!(a-c=n))break;t=[e.pop(),...t]}return[e,t]},[[],[...e]]),Object($.a)((e,t)=>e[0]===t[0]&&e[1]===t[1])))).pipe(Object(i.a)(([e,t])=>({prev:e.map(([e])=>e),next:t.map(([e])=>e)})),Object(v.a)({prev:[],next:[]}),Object(Ae.a)(2,1),Object(i.a)(([e,t])=>e.prev.lengthc.complete()),Object(i.a)(t=>Object.assign({ref:e},t)))}var pt=c(14);function ut(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}document.documentElement.classList.remove("no-js"),document.documentElement.classList.add("js");const lt=function(){const e=new u.a;return Object(l.a)(document,"DOMContentLoaded").pipe(Object(f.a)(document)).subscribe(e),e}(),ft=new N.a(H()),dt=Object(l.a)(window,"hashchange").pipe(Object(i.a)(z),Object(v.a)(z()),Object(o.a)(e=>e.length>0),Object(L.a)()).pipe(Object(s.a)(e=>Object(y.a)(d(`[id="${e}"]`)))),Ot=Object(l.a)(window,"keydown").pipe(Object(o.a)(e=>!(e.metaKey||e.ctrlKey)),Object(i.a)(e=>{return{mode:(t="search",P[t].checked?"search":"global"),type:e.key,claim(){e.preventDefault(),e.stopPropagation()}};var t}),Object(o.a)(({mode:e})=>{if("global"===e){const e=j();if(void 0!==e)return!function(e){switch(e.tagName){case"INPUT":case"SELECT":case"TEXTAREA":return!0;default:return e.isContentEditable}}(e)}return!0}),Object(L.a)()),jt=Object(J.a)([Object(a.a)(Object(l.a)(window,"scroll",{passive:!0}),Object(l.a)(window,"resize",{passive:!0})).pipe(Object(i.a)(B),Object(v.a)(B())),Object(l.a)(window,"resize",{passive:!0}).pipe(Object(i.a)(Q),Object(v.a)(Q()))]).pipe(Object(i.a)(([e,t])=>({offset:e,size:t})),Object(b.a)(1)),ht=I("(min-width: 960px)"),mt=I("(min-width: 1220px)"),gt=Object(a.a)(I("print").pipe(Object(o.a)(Boolean)),Object(l.a)(window,"beforeprint")).pipe(Object(f.a)(void 0)),vt=new n.a;!function({alert$:e}){se.a.isSupported()&&new Le.a(e=>{new se.a("[data-clipboard-target], [data-clipboard-text]").on("success",t=>e.next(t))}).subscribe(()=>e.next(ne("clipboard.copied")))}({alert$:vt}),ce("navigation.instant")&&function({document$:e,location$:t,viewport$:c}){const n=te();if("file:"===location.protocol)return;"scrollRestoration"in history&&(history.scrollRestoration="manual",Object(l.a)(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}));const r=d("link[rel='shortcut icon']");void 0!==r&&(r.href=r.href);const p=function(e,t){const c=new DOMParser;return F(e,t).pipe(Object(s.a)(e=>e.text()),Object(i.a)(e=>c.parseFromString(e,"text/xml")),Object(b.a)(1))}(n.base+"/sitemap.xml").pipe(Object(i.a)(e=>function(e){if(e.length<2)return e;const[t,c]=e.sort((e,t)=>e.length-t.length);let n=0;if(t===c)n=t.length;else for(;t.charCodeAt(n)==t.charCodeAt(n);)n++;const a=te();return e.map(e=>e.replace(t.slice(0,n),a.base+"/"))}(h("loc",e).map(e=>e.textContent))),Object(s.a)(e=>Object(l.a)(document.body,"click").pipe(Object(o.a)(e=>!e.metaKey&&!e.ctrlKey),Object(s.a)(t=>{if(t.target instanceof HTMLElement){const c=t.target.closest("a");if(c&&!c.target&&e.includes(c.href))return t.preventDefault(),Object(y.a)({url:new URL(c.href)})}return x.a}))),Object(L.a)()),u=Object(l.a)(window,"popstate").pipe(Object(o.a)(e=>null!==e.state),Object(i.a)(e=>({url:new URL(location.href),offset:e.state})),Object(L.a)());Object(a.a)(p,u).pipe(Object($.a)((e,t)=>e.url.href===t.url.href),Object(i.a)(({url:e})=>e)).subscribe(t);const f=t.pipe(Object(W.a)("pathname"),Object(Ue.a)(1),Object(s.a)(e=>F(e.href).pipe(Object(Ne.a)(()=>(function(e){location.href=e.href}(e),x.a)))),Object(L.a)());p.pipe(Object(Me.a)(f)).subscribe(({url:e})=>{history.pushState({},"",e.toString())});const O=new DOMParser;f.pipe(Object(s.a)(e=>e.text()),Object(i.a)(e=>O.parseFromString(e,"text/html"))).subscribe(e),Object(a.a)(p,u).pipe(Object(Me.a)(e)).subscribe(({url:e,offset:t})=>{e.hash&&!t?function(e){const t=m("a");t.href=e,t.addEventListener("click",e=>e.stopPropagation()),t.click()}(e.hash):K(t||{y:0})}),e.pipe(Object(Ue.a)(1)).subscribe(e=>{for(const t of["title","link[rel='canonical']","meta[name='author']","meta[name='description']","[data-md-component=announce]","[data-md-component=header-title]","[data-md-component=container]","[data-md-component=skip]"]){const c=d(t),n=d(t,e);void 0!==c&&void 0!==n&&g(c,n)}}),e.pipe(Object(Ue.a)(1),Object(i.a)(()=>ae("container")),Object(s.a)(e=>Object(y.a)(...h("script",e))),Object(He.a)(e=>{const t=m("script");return e.src?(t.src=e.src,g(e,t),new Le.a(e=>{t.onload=()=>e.complete()})):(t.textContent=e.textContent,g(e,t),Pe.a)})).subscribe(),c.pipe(Object(ze.a)(p),Object(Ie.a)(250),Object(W.a)("offset")).subscribe(({offset:e})=>{history.replaceState(e,"")}),Object(a.a)(p,u).pipe(Object(Ae.a)(2,1),Object(o.a)(([e,t])=>e.url.pathname===t.url.pathname),Object(i.a)(([,e])=>e)).subscribe(({offset:e})=>{K(e||{y:0})})}({document$:lt,location$:ft,viewport$:jt}),Object(a.a)(ft,dt).subscribe(()=>U("drawer",!1)),Ot.pipe(Object(o.a)(({mode:e})=>"global"===e)).subscribe(e=>{switch(e.type){case"p":case",":const e=d("[href][rel=prev]");void 0!==e&&e.click();break;case"n":case".":const t=d("[href][rel=next]");void 0!==t&&t.click()}}),function({document$:e}){e.subscribe(()=>{for(const e of h("[data-md-state=indeterminate]"))e.setAttribute("data-md-state",""),e.indeterminate=!0,e.checked=!1})}({document$:lt}),function({document$:e}){e.pipe(Object(s.a)(()=>Object(y.a)(...h("[data-md-scrollfix]"))),Object(E.a)(e=>e.removeAttribute("data-md-scrollfix")),Object(o.a)(ut),Object(pt.a)(e=>Object(l.a)(e,"touchstart").pipe(Object(f.a)(e)))).subscribe(e=>{const t=e.scrollTop;0===t?e.scrollTop=1:t+e.offsetHeight===e.scrollHeight&&(e.scrollTop=t-1)})}({document$:lt});const wt=($t=ae("header"),yt={viewport$:jt},Object(r.a)(()=>{const e=getComputedStyle($t);return Object(y.a)("sticky"===e.position||"-webkit-sticky"===e.position)}).pipe(Object(Te.a)(R($t),Se(yt)),Object(i.a)(([e,{height:t},c])=>({height:e?t:0,sticky:e,hidden:c})),Object($.a)((e,t)=>e.sticky===t.sticky&&e.height===t.height&&e.hidden===t.hidden),Object(b.a)(1)));var $t,yt;const xt=lt.pipe(Object(i.a)(()=>ae("main")),Object(s.a)(e=>function(e,{viewport$:t,header$:c}){const n=c.pipe(Object(i.a)(({height:e})=>e),Object($.a)()),a=n.pipe(Object(s.a)(()=>R(e).pipe(Object(i.a)(({height:t})=>({top:e.offsetTop,bottom:e.offsetTop+t})),Object(W.a)("bottom"))));return Object(J.a)([n,a,t]).pipe(Object(i.a)(([e,{top:t,bottom:c},{offset:{y:n},size:{height:a}}])=>({offset:t-e,height:a=Math.max(0,a-Math.max(0,t-n,e)-Math.max(0,a+n-c)),active:t-e<=n})),Object($.a)((e,t)=>e.offset===t.offset&&e.height===t.height&&e.active===t.active))}(e,{viewport$:jt,header$:wt})),Object(b.a)(1)),_t=Object(a.a)(...re("dialog").map(e=>ke(e,{alert$:vt})),...re("header").map(e=>function(e,{header$:t,main$:c}){const a=new n.a;return a.pipe(Object(W.a)("active"),Object(Te.a)(t),Object(Ee.a)(xe.a)).subscribe(([{active:t},{hidden:c}])=>{t?function(e,t){e.setAttribute("data-md-state",t)}(e,c?"hidden":"shadow"):function(e){e.removeAttribute("data-md-state")}(e)}),c.subscribe(e=>a.next(e)),t.pipe(Object(i.a)(t=>Object.assign({ref:e},t)))}(e,{viewport$:jt,header$:wt,main$:xt})),...re("search").map(e=>et(e,{keyboard$:Ot})),...re("source").map(e=>ot(e)),...re("tabs").map(e=>it(e,{viewport$:jt,header$:wt}))),Et=Object(r.a)(()=>Object(a.a)(...re("content").map(e=>function(e,{target$:t,viewport$:c,print$:n}){return Object(a.a)(...h("pre > code",e).map(e=>ve(e,{viewport$:c})),...h("table:not([class])",e).map(e=>ye(e)),...h("details",e).map(e=>we(e,{target$:t,print$:n})))}(e,{target$:dt,viewport$:jt,print$:gt})),...re("header-title").map(e=>Re(e,{viewport$:jt,header$:wt})),...re("sidebar").map(e=>"navigation"===e.getAttribute("data-md-type")?D(mt,()=>ct(e,{viewport$:jt,header$:wt,main$:xt})):D(ht,()=>ct(e,{viewport$:jt,header$:wt,main$:xt}))),...re("toc").map(e=>bt(e,{viewport$:jt,header$:wt})))),kt=lt.pipe(Object(s.a)(()=>Et),Object(p.a)(_t),Object(b.a)(1));kt.subscribe()}})); +//# sourceMappingURL=bundle.9a5a6e7c.min.js.map \ No newline at end of file diff --git a/material/assets/javascripts/bundle.9a5a6e7c.min.js.map b/material/assets/javascripts/bundle.9a5a6e7c.min.js.map new file mode 100644 index 000000000..fb59f4439 --- /dev/null +++ b/material/assets/javascripts/bundle.9a5a6e7c.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/assets/javascripts/browser/element/_/index.ts","webpack:///./src/assets/javascripts/browser/element/focus/index.ts","webpack:///./src/assets/javascripts/browser/element/size/index.ts","webpack:///./src/assets/javascripts/browser/element/offset/index.ts","webpack:///./src/assets/javascripts/browser/toggle/index.ts","webpack:///./src/assets/javascripts/browser/location/_/index.ts","webpack:///./src/assets/javascripts/browser/location/hash/index.ts","webpack:///./src/assets/javascripts/browser/media/index.ts","webpack:///./src/assets/javascripts/browser/request/index.ts","webpack:///./src/assets/javascripts/browser/viewport/offset/index.ts","webpack:///./src/assets/javascripts/browser/viewport/size/index.ts","webpack:///./src/assets/javascripts/browser/viewport/_/index.ts","webpack:///./src/assets/javascripts/_/index.ts","webpack:///./src/assets/javascripts/components/_/index.ts","webpack:///./src/assets/javascripts/templates/search/index.tsx","webpack:///./src/assets/javascripts/actions/anchor/index.ts","webpack:///./src/assets/javascripts/utilities/h/index.ts","webpack:///./src/assets/javascripts/utilities/string/index.ts","webpack:///./src/assets/javascripts/actions/tabs/index.ts","webpack:///./src/assets/javascripts/components/content/code/index.ts","webpack:///./src/assets/javascripts/actions/_/index.ts","webpack:///./src/assets/javascripts/templates/clipboard/index.tsx","webpack:///./src/assets/javascripts/components/content/details/index.ts","webpack:///./src/assets/javascripts/components/content/table/index.ts","webpack:///./src/assets/javascripts/templates/table/index.tsx","webpack:///./src/assets/javascripts/components/dialog/index.ts","webpack:///./src/assets/javascripts/actions/dialog/index.ts","webpack:///./src/assets/javascripts/components/header/_/index.ts","webpack:///./src/assets/javascripts/components/header/title/index.ts","webpack:///./src/assets/javascripts/actions/header/title/index.ts","webpack:///./src/assets/javascripts/integrations/search/worker/message/index.ts","webpack:///./src/assets/javascripts/integrations/search/query/transform/index.ts","webpack:///./src/assets/javascripts/integrations/search/worker/_/index.ts","webpack:///./src/assets/javascripts/browser/worker/index.ts","webpack:///./src/assets/javascripts/components/search/query/index.ts","webpack:///./src/assets/javascripts/actions/search/query/index.ts","webpack:///./src/assets/javascripts/components/search/result/index.ts","webpack:///./src/assets/javascripts/actions/search/result/index.ts","webpack:///./src/assets/javascripts/components/search/_/index.ts","webpack:///./src/assets/javascripts/browser/element/selection/index.ts","webpack:///./src/assets/javascripts/components/sidebar/index.ts","webpack:///./src/assets/javascripts/actions/sidebar/index.ts","webpack:///./src/assets/javascripts/components/source/facts/_/index.ts","webpack:///./src/assets/javascripts/components/source/facts/github/index.ts","webpack:///./src/assets/javascripts/components/source/facts/gitlab/index.ts","webpack:///./src/assets/javascripts/components/source/_/index.ts","webpack:///./src/assets/javascripts/actions/source/index.ts","webpack:///./src/assets/javascripts/templates/source/index.tsx","webpack:///./src/assets/javascripts/components/tabs/index.ts","webpack:///./src/assets/javascripts/components/toc/index.ts","webpack:///./src/assets/javascripts/patches/scrollfix/index.ts","webpack:///./src/assets/javascripts/index.ts","webpack:///./src/assets/javascripts/browser/document/index.ts","webpack:///./src/assets/javascripts/browser/keyboard/index.ts","webpack:///./src/assets/javascripts/integrations/clipboard/index.ts","webpack:///./src/assets/javascripts/integrations/instant/index.ts","webpack:///./src/assets/javascripts/patches/indeterminate/index.ts","webpack:///./src/assets/javascripts/components/main/index.ts","webpack:///./src/assets/javascripts/actions/header/_/index.ts","webpack:///./src/assets/javascripts/components/content/_/index.ts"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","0","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","window","oldJsonpFunction","slice","getElement","selector","node","document","querySelector","undefined","getElementOrThrow","el","ReferenceError","getActiveElement","activeElement","HTMLElement","getElements","Array","from","querySelectorAll","createElement","tagName","replaceElement","source","target","replaceWith","setElementFocus","focus","blur","entry$","Subject","observer$","defer","of","ResizeObserver","entries","entry","next","pipe","switchMap","resize","startWith","finalize","disconnect","shareReplay","getElementSize","width","offsetWidth","height","offsetHeight","getElementContentSize","scrollWidth","scrollHeight","watchElementSize","tap","observer","observe","filter","unobserve","map","contentRect","getElementOffset","x","scrollLeft","y","scrollTop","watchElementThreshold","threshold","merge","fromEvent","watchElementOffset","visible","distinctUntilChanged","toggles","drawer","search","setToggle","checked","click","getLocation","URL","location","href","getLocationHash","hash","substring","watchMedia","query","media","matchMedia","ev","matches","at","query$","factory","active","request","url","options","credentials","fetch","res","status","requestJSON","json","getViewportOffset","Math","max","pageXOffset","pageYOffset","setViewportOffset","scrollTo","getViewportSize","innerWidth","innerHeight","watchViewportAt","viewport$","header$","size$","distinctUntilKeyChanged","offset$","combineLatest","offsetLeft","offsetTop","offset","size","JSON","parse","textContent","configuration","feature","flag","features","includes","translation","translations","replace","toString","getComponentElement","type","getComponentElements","base","Flag","setAnchorState","state","setAttribute","resetAnchorState","removeAttribute","setAnchorActive","classList","toggle","resetAnchorActive","remove","appendChild","child","innerHTML","Node","isArray","h","tag","attributes","children","attr","keys","round","toFixed","resetTabsState","renderSearchDocument","parent","PARENT","teaser","TEASER","missing","terms","flat","class","tabIndex","join","score","title","text","truncate","mountCodeBlock","internal$","withLatestFrom","subscribe","scroll","hover","setFocusable","resetFocusable","isSupported","closest","id","insertBefore","container$","container","input","share","watchCodeBlock","complete","ref","mountDetails","scrollIntoView","target$","print$","details","mergeWith","mapTo","watchDetails","sentinel","mountDataTable","mountDialog","observeOn","animationFrame","message","open","firstElementChild","setDialogMessage","setDialogState","resetDialogState","_el","alert$","delay","watchDialog","isHidden","direction$","bufferCount","a","b","hidden$","abs","direction","search$","watchToggle","mountHeaderTitle","setHeaderTitleState","resetHeaderTitleState","headline","watchHeaderTitle","SearchMessageType","defaultTransform","split","index","trim","isSearchReadyMessage","READY","isSearchQueryMessage","QUERY","isSearchResultMessage","RESULT","setupSearchIndex","config","docs","lang","separator","pipeline","Boolean","setupSearchWorker","worker","Worker","tx$","rx$","throttle","leading","trailing","postMessage","switchMapTo","watchWorker","SETUP","watchSearchQuery","fn","__search","transform","focus$","watchElementFocus","value$","mountSearchQuery","placeholder","setSearchQueryPlaceholder","resetSearchQueryPlaceholder","form","takeUntil","takeLast","mountSearchResult","boundary$","parentElement","meta","setSearchResultMeta","resetSearchResultMeta","list","resetSearchResultList","zipWith","chunk","addToSearchResultList","findIndex","doc","article","best","more","section","renderSearchResult","mountSearch","keyboard$","protocol","sample","take","claim","els","indexOf","HTMLInputElement","Error","select","setElementSelection","mountSidebar","scrollwrap","style","setSidebarHeight","top","setSidebarOffset","resetSidebarOffset","resetSidebarHeight","main$","adjust","min","locked","watchSidebar","fetchSourceFacts","match","toLowerCase","user","repo","stargazers_count","forks_count","public_repos","defaultIfEmpty","fetchSourceFactsFromGitHub","slug","project","encodeURIComponent","star_count","fetchSourceFactsFromGitLab","fetch$","mountSource","facts","lastElementChild","setSourceFacts","fact","renderSourceFacts","setSourceState","digest","len","charCodeAt","sessionStorage","getItem","setItem","stringify","err","catchError","watchSource","mountTabs","hidden","setTabsState","watchTabs","mountTableOfContents","prev","anchor","anchors","table","Map","decodeURIComponent","set","adjust$","header","body","path","reduce","pop","reverse","scan","watchTableOfContents","isAppleDevice","test","navigator","userAgent","documentElement","add","document$","ReplaySubject","watchDocument","BehaviorSubject","metaKey","ctrlKey","preventDefault","stopPropagation","isContentEditable","isSusceptibleToKeyboard","passive","tablet$","screen$","Observable","subscriber","on","setupClipboardJS","location$","history","scrollRestoration","favicon","push$","dom","DOMParser","parseFromString","requestXML","sitemap","urls","root","sort","preprocess","pop$","response$","skip","setLocation","pushState","addEventListener","setLocationHash","replacement","concatMap","script","src","onload","skipUntil","debounceTime","replaceState","pathname","setupInstantLoading","indeterminate","patchIndeterminate","mergeMap","patchScrollfix","styles","getComputedStyle","position","combineLatestWith","sticky","border$","bottom","watchMain","control$","setHeaderState","resetHeaderState","main","mountHeader","content$","mountContent","getAttribute","component$"],"mappings":"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","file":"assets/javascripts/bundle.9a5a6e7c.min.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t0: 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([50,1]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","/*\n * Copyright (c) 2016-2021 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 an 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 getElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElement(\n selector: string, node?: ParentNode\n): T | undefined\n\nexport function getElement(\n selector: string, node: ParentNode = document\n): T | undefined {\n return node.querySelector(selector) || undefined\n}\n\n/**\n * Retrieve an element matching a query selector or throw a reference error\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 getElementOrThrow(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElementOrThrow(\n selector: string, node?: ParentNode\n): T\n\nexport function getElementOrThrow(\n selector: string, node: ParentNode = document\n): T {\n const el = getElement(selector, node)\n if (typeof el === \"undefined\")\n throw new ReferenceError(\n `Missing element: expected \"${selector}\" to be present`\n )\n return el\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\n : undefined\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\n/**\n * Create an element\n *\n * @template T - Tag name type\n *\n * @param tagName - Tag name\n *\n * @returns Element\n */\nexport function createElement(\n tagName: T\n): HTMLElementTagNameMap[T] {\n return document.createElement(tagName)\n}\n\n/**\n * Replace an element with another element\n *\n * @param source - Source element\n * @param target - Target element\n */\nexport function replaceElement(\n source: HTMLElement, target: Node\n): void {\n source.replaceWith(target)\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent, merge } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\nimport { getActiveElement } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set element focus\n *\n * @param el - Element\n * @param value - Whether the element should be focused\n */\nexport function setElementFocus(\n el: HTMLElement, value = true\n): void {\n if (value)\n el.focus()\n else\n el.blur()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element focus\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(el, \"focus\"),\n fromEvent(el, \"blur\")\n )\n .pipe(\n map(({ type }) => type === \"focus\"),\n startWith(el === getActiveElement())\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 of\n} from \"rxjs\"\nimport {\n filter,\n finalize,\n map,\n shareReplay,\n startWith,\n switchMap,\n tap\n} from \"rxjs/operators\"\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(resize => NEVER.pipe(startWith(resize))\n .pipe(\n finalize(() => resize.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(el: HTMLElement): ElementSize {\n return {\n width: el.offsetWidth,\n height: el.offsetHeight\n }\n}\n\n/**\n * Retrieve element content size, i.e. including overflowing content\n *\n * @param el - Element\n *\n * @returns Element size\n */\nexport function getElementContentSize(el: HTMLElement): ElementSize {\n return {\n width: el.scrollWidth,\n height: el.scrollHeight\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 * @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(({ contentRect }) => ({\n width: contentRect.width,\n height: contentRect.height\n }))\n )\n ),\n startWith(getElementSize(el))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent, merge } from \"rxjs\"\nimport { distinctUntilChanged, map, startWith } from \"rxjs/operators\"\n\nimport { getElementContentSize, getElementSize } from \"../size\"\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(el: HTMLElement): ElementOffset {\n return {\n x: el.scrollLeft,\n y: el.scrollTop\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(el, \"scroll\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n map(() => getElementOffset(el)),\n startWith(getElementOffset(el))\n )\n}\n\n/**\n * Watch element threshold\n *\n * This function returns an observable which emits whether the bottom scroll\n * offset of an elements is within a certain threshold.\n *\n * @param el - Element\n * @param threshold - Threshold\n *\n * @returns Element threshold observable\n */\nexport function watchElementThreshold(\n el: HTMLElement, threshold = 16\n): Observable {\n return watchElementOffset(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-2021 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, fromEvent } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\nimport { getElementOrThrow } 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: getElementOrThrow(\"[data-md-toggle=drawer]\"),\n search: getElementOrThrow(\"[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-2021 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 { BehaviorSubject, Subject } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location\n *\n * This function will return a `URL` object (and not `Location`) in order to\n * normalize typings across the application. Furthermore, locations need to be\n * tracked without setting them and `Location` is a singleton which represents\n * the 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 BehaviorSubject(getLocation())\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent, of } from \"rxjs\"\nimport { filter, map, share, startWith, switchMap } from \"rxjs/operators\"\n\nimport { createElement, getElement } from \"~/browser\"\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 = createElement(\"a\")\n el.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 share()\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 switchMap(id => of(getElement(`[id=\"${id}\"]`)!))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { NEVER, Observable, fromEvent, merge } from \"rxjs\"\nimport {\n filter,\n map,\n mapTo,\n startWith,\n switchMap\n} from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch media query\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 fromEvent(media, \"change\")\n .pipe(\n map(ev => ev.matches),\n startWith(media.matches)\n )\n}\n\n/**\n * Watch print mode, cross-browser\n *\n * @returns Print observable\n */\nexport function watchPrint(): Observable {\n return merge(\n watchMedia(\"print\").pipe(filter(Boolean)), /* Webkit */\n fromEvent(window, \"beforeprint\") /* IE, FF */\n )\n .pipe(\n mapTo(undefined)\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() : NEVER)\n )\n}\n","/*\n * Copyright (c) 2016-2021 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, from } from \"rxjs\"\nimport {\n filter,\n map,\n shareReplay,\n switchMap\n} from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the given URL\n *\n * @param url - Request URL\n * @param options - Request options\n *\n * @returns Response observable\n */\nexport function request(\n url: string, options: RequestInit = { credentials: \"same-origin\" }\n): Observable {\n return from(fetch(url, options))\n .pipe(\n filter(res => res.status === 200),\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 - Request options\n *\n * @returns Data observable\n */\nexport function requestJSON(\n 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 - Request options\n *\n * @returns Data observable\n */\nexport function requestXML(\n 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-2021 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, fromEvent, merge } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\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, pageXOffset),\n y: Math.max(0, pageYOffset)\n }\n}\n\n/**\n * Set viewport offset\n *\n * @param offset - Viewport offset\n */\nexport function setViewportOffset(\n { x, y }: Partial\n): void {\n window.scrollTo(x || 0, y || 0)\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-2021 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, fromEvent } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\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-2021 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, combineLatest } from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n map,\n shareReplay\n} from \"rxjs/operators\"\n\nimport { Header } from \"~/components\"\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 * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch at options\n */\ninterface WatchAtOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\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/**\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$ }: WatchAtOptions\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((): ViewportOffset => ({\n x: el.offsetLeft,\n y: el.offsetTop\n }))\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-2021 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 { getElementOrThrow, getLocation } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flag\n */\nexport type Flag =\n | \"header.autohide\" /* Hide header */\n | \"navigation.expand\" /* Automatic expansion */\n | \"navigation.instant\" /* Instant loading */\n | \"navigation.sections\" /* Sections navigation */\n | \"navigation.tabs\" /* Tabs navigation */\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\n/**\n * Translations\n */\nexport type Translations = Record\n\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}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration and make base URL absolute\n */\nconst script = getElementOrThrow(\"#__config\")\nconst config: Config = JSON.parse(script.textContent!)\nconfig.base = new URL(config.base, getLocation())\n .toString()\n .replace(/\\/$/, \"\")\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 - Value to be replaced\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-2021 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 { getElementOrThrow, getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component\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 | \"main\" /* Main area */\n | \"search\" /* Search */\n | \"search-query\" /* Search input */\n | \"search-result\" /* Search results */\n | \"sidebar\" /* Sidebar */\n | \"skip\" /* Skip link */\n | \"source\" /* Repository information */\n | \"tabs\" /* Navigation tabs */\n | \"toc\" /* Table of contents */\n\n/**\n * A 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 * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the element for a given component or throw a reference error\n *\n * @template T - Element type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getComponentElement(\n type: ComponentType, node: ParentNode = document\n): T {\n return getElementOrThrow(`[data-md-component=${type}]`, node)\n}\n\n/**\n * Retrieve all elements for a given component\n *\n * @template T - Element type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getComponentElements(\n type: ComponentType, node: ParentNode = document\n): T[] {\n return getElements(`[data-md-component=${type}]`, node)\n}\n","/*\n * Copyright (c) 2016-2021 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 {\n SearchDocument,\n SearchMetadata,\n SearchResult\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 .map(key => [{key}, \" \"])\n .flat()\n .slice(0, -1)\n\n /* Render article or section, depending on flags */\n const url = document.location\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 {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 renderSearchResult(\n result: SearchResult\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-2021 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 * Set anchor state\n *\n * @param el - Anchor element\n * @param state - Anchor state\n */\nexport function setAnchorState(\n el: HTMLElement, state: \"blur\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset anchor state\n *\n * @param el - Anchor element\n */\nexport function resetAnchorState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Set anchor active\n *\n * @param el - Anchor element\n * @param value - Whether the anchor is active\n */\nexport function setAnchorActive(\n el: HTMLElement, value: boolean\n): void {\n el.classList.toggle(\"md-nav__link--active\", value)\n}\n\n/**\n * Reset anchor active\n *\n * @param el - Anchor element\n */\nexport function resetAnchorActive(\n el: HTMLElement\n): void {\n el.classList.remove(\"md-nav__link--active\")\n}\n","/*\n * Copyright (c) 2016-2021 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 * @param tag - HTML tag\n * @param attributes - HTML attributes\n * @param children - Child elements\n *\n * @returns Element\n */\nexport function h(\n tag: string, attributes: Attributes | null, ...children: Child[]\n): HTMLElement {\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\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-2021 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/**\n * Simple hash function\n *\n * @see https://bit.ly/2wsVjJ4 - Original source\n *\n * @param value - Value to be hashed\n *\n * @returns Hash as 32bit integer\n */\nexport function hash(value: string): number {\n let h = 0\n for (let i = 0, len = value.length; i < len; i++) {\n h = ((h << 5) - h) + value.charCodeAt(i)\n h |= 0 // Convert to 32bit integer\n }\n return h\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set tabs state\n *\n * @param el - Tabs element\n * @param state - Tabs state\n */\nexport function setTabsState(\n el: HTMLElement, state: \"hidden\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset tabs state\n *\n * @param el - Tabs element\n */\nexport function resetTabsState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2021 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 NEVER,\n Observable,\n Subject,\n fromEvent,\n merge,\n of\n} from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n finalize,\n map,\n share,\n switchMap,\n tap,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport { resetFocusable, setFocusable } from \"~/actions\"\nimport {\n Viewport,\n getElementContentSize,\n getElementSize,\n getElements,\n watchMedia\n} from \"~/browser\"\nimport { renderClipboardButton } from \"~/templates\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Code block\n */\nexport interface CodeBlock {\n scroll: boolean /* Code block overflows */\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}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Global index for Clipboard.js integration\n */\nlet index = 0\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch code block\n *\n * This function will monitor size changes of the viewport, as well as switches\n * of content tabs with embedded code blocks, as both may trigger overflow.\n *\n * @param el - Code block element\n * @param options - Options\n *\n * @returns Code block observable\n */\nexport function watchCodeBlock(\n el: HTMLElement, { viewport$ }: WatchOptions\n): Observable {\n const container$ = of(el)\n .pipe(\n switchMap(child => {\n const container = child.closest(\"[data-tabs]\")\n if (container instanceof HTMLElement) {\n return merge(\n ...getElements(\"input\", container)\n .map(input => fromEvent(input, \"change\"))\n )\n }\n return NEVER\n }),\n share()\n )\n\n /* Check overflow on resize and tab change */\n return merge(\n viewport$.pipe(distinctUntilKeyChanged(\"size\")),\n container$\n )\n .pipe(\n map(() => {\n const visible = getElementSize(el)\n const content = getElementContentSize(el)\n return {\n scroll: content.width > visible.width\n }\n }),\n distinctUntilKeyChanged(\"scroll\")\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 *\n * @param el - Code block element\n * @param options - Options\n *\n * @returns Code block component observable\n */\nexport function mountCodeBlock(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const internal$ = new Subject()\n internal$\n .pipe(\n withLatestFrom(watchMedia(\"(hover)\"))\n )\n .subscribe(([{ scroll }, hover]) => {\n if (scroll && hover)\n setFocusable(el)\n else\n resetFocusable(el)\n })\n\n /* Inject button for Clipboard.js integration */\n if (ClipboardJS.isSupported()) {\n const parent = el.closest(\"pre\")!\n parent.id = `__code_${index++}`\n parent.insertBefore(\n renderClipboardButton(parent.id),\n el\n )\n }\n\n /* Create and return component */\n return watchCodeBlock(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set focusable property\n *\n * @param el - Element\n * @param value - Tabindex value\n */\nexport function setFocusable(\n el: HTMLElement, value = 0\n): void {\n el.setAttribute(\"tabindex\", value.toString())\n}\n\n/**\n * Reset focusable property\n *\n * @param el - Element\n */\nexport function resetFocusable(\n el: HTMLElement\n): void {\n el.removeAttribute(\"tabindex\")\n}\n\n/**\n * Set scroll lock\n *\n * @param el - Scrollable element\n * @param value - Vertical offset\n */\nexport function setScrollLock(\n el: HTMLElement, value: number\n): void {\n el.setAttribute(\"data-md-state\", \"lock\")\n el.style.top = `-${value}px`\n}\n\n/**\n * Reset scroll lock\n *\n * @param el - Scrollable element\n */\nexport function resetScrollLock(\n el: HTMLElement\n): void {\n const value = -1 * parseInt(el.style.top, 10)\n el.removeAttribute(\"data-md-state\")\n el.style.top = \"\"\n if (value)\n window.scrollTo(0, value)\n}\n","/*\n * Copyright (c) 2016-2021 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-2021 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, Subject } from \"rxjs\"\nimport {\n filter,\n finalize,\n map,\n mapTo,\n mergeWith,\n tap\n} from \"rxjs/operators\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Details\n */\nexport interface Details {}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Print observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* 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 return target$\n .pipe(\n map(target => target.closest(\"details:not([open])\")!),\n filter(details => el === details),\n mergeWith(print$),\n mapTo(el)\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 const internal$ = new Subject
    ()\n internal$.subscribe(() => {\n el.setAttribute(\"open\", \"\")\n el.scrollIntoView()\n })\n\n /* Create and return component */\n return watchDetails(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n mapTo({ ref: el })\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { createElement, replaceElement } from \"~/browser\"\nimport { renderTable } from \"~/templates\"\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 = createElement(\"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 they\n * can be 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 replaceElement(el, sentinel)\n replaceElement(sentinel, renderTable(el))\n\n /* Create and return component */\n return of({ ref: el })\n}\n","/*\n * Copyright (c) 2016-2021 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-2021 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 merge,\n of\n} from \"rxjs\"\nimport {\n delay,\n finalize,\n map,\n observeOn,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport {\n resetDialogState,\n setDialogMessage,\n setDialogState\n} from \"~/actions\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Dialog\n */\nexport interface Dialog {\n message: string /* Dialog message */\n open: boolean /* Dialog is visible */\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(open => ({ message, open }))\n )\n )\n )\n}\n\n/**\n * Mount dialog\n *\n * This function makes the dialog in the right corner appear when a new alert\n * is 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 internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler)\n )\n .subscribe(({ message, open }) => {\n setDialogMessage(el, message)\n if (open)\n setDialogState(el, \"open\")\n else\n resetDialogState(el)\n })\n\n /* Create and return component */\n return watchDialog(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set dialog message\n *\n * @param el - Dialog element\n * @param value - Dialog message\n */\nexport function setDialogMessage(\n el: HTMLElement, value: string\n): void {\n el.firstElementChild!.innerHTML = value\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Set dialog state\n *\n * @param el - Dialog element\n * @param state - Dialog state\n */\nexport function setDialogState(\n el: HTMLElement, state: \"open\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset dialog state\n *\n * @param el - Dialog element\n */\nexport function resetDialogState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2021 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 combineLatest,\n defer,\n of\n} from \"rxjs\"\nimport {\n bufferCount,\n combineLatestWith,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n observeOn,\n shareReplay,\n startWith,\n switchMap\n} from \"rxjs/operators\"\n\nimport { feature } from \"~/_\"\nimport { resetHeaderState, setHeaderState } from \"~/actions\"\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 sticky: boolean /* Header stickyness */\n hidden: boolean /* User scrolled past threshold */\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 autohiding */\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(() => {\n const styles = getComputedStyle(el)\n return of(\n styles.position === \"sticky\" ||\n styles.position === \"-webkit-sticky\"\n )\n })\n .pipe(\n combineLatestWith(watchElementSize(el), isHidden(options)),\n map(([sticky, { height }, hidden]) => ({\n height: sticky ? height : 0,\n sticky,\n hidden\n })),\n distinctUntilChanged((a, b) => (\n a.sticky === b.sticky &&\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 const internal$ = new Subject
    ()\n internal$\n .pipe(\n distinctUntilKeyChanged(\"active\"),\n combineLatestWith(header$),\n observeOn(animationFrameScheduler)\n )\n .subscribe(([{ active }, { hidden }]) => {\n if (active)\n setHeaderState(el, hidden ? \"hidden\" : \"shadow\")\n else\n resetHeaderState(el)\n })\n\n /* Connect to long-living subject and return component */\n main$.subscribe(main => internal$.next(main))\n return header$\n .pipe(\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 animationFrameScheduler\n} from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n finalize,\n map,\n observeOn,\n tap\n} from \"rxjs/operators\"\n\nimport {\n resetHeaderTitleState,\n setHeaderTitleState\n} from \"~/actions\"\nimport {\n Viewport,\n getElement,\n getElementSize,\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 /* User scrolled past first headline */\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: HTMLHeadingElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchViewportAt(el, { header$, viewport$ })\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 const internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n )\n .subscribe(({ active }) => {\n if (active)\n setHeaderTitleState(el, \"active\")\n else\n resetHeaderTitleState(el)\n })\n\n /* Obtain headline, if any */\n const headline = getElement(\"article h1\")\n if (typeof headline === \"undefined\")\n return NEVER\n\n /* Create and return component */\n return watchHeaderTitle(headline, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set header title state\n *\n * @param el - Header title element\n * @param state - Header title state\n */\nexport function setHeaderTitleState(\n el: HTMLElement, state: \"active\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset header title state\n *\n * @param el - Header title element\n */\nexport function resetHeaderTitleState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2021 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 * A 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 * A message indicating the search index is ready\n */\nexport interface SearchReadyMessage {\n type: SearchMessageType.READY /* Message type */\n}\n\n/**\n * A message containing a search query\n */\nexport interface SearchQueryMessage {\n type: SearchMessageType.QUERY /* Message type */\n data: string /* Message data */\n}\n\n/**\n * A 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 * A 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-2021 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` 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-2021 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 { ObservableInput, Subject, from } from \"rxjs\"\nimport { map, share } from \"rxjs/operators\"\n\nimport { configuration, translation } from \"~/_\"\nimport { WorkerHandler, watchWorker } from \"~/browser\"\n\nimport { SearchIndex, SearchIndexPipeline } from \"../../_\"\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(\n { config, docs, index }: SearchIndex\n): 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 SearchIndexPipeline\n\n /* Return search index after defaulting */\n return { config, docs, index, pipeline }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search worker\n *\n * This function will create a web worker to set up and query the search index\n * which is done using `lunr`. 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)\n for (const document of result)\n document.location = `${config.base}/${document.location}`\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 }))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Return search worker */\n return { tx$, rx$ }\n}\n","/*\n * Copyright (c) 2016-2021 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, Subject, fromEvent } from \"rxjs\"\nimport {\n map,\n share,\n switchMapTo,\n tap,\n throttle\n} from \"rxjs/operators\"\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 switchMapTo(rx$),\n share()\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 fromEvent,\n merge\n} from \"rxjs\"\nimport {\n delay,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n startWith,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs/operators\"\n\nimport {\n resetSearchQueryPlaceholder,\n setSearchQueryPlaceholder\n} from \"~/actions\"\nimport {\n setElementFocus,\n setToggle,\n watchElementFocus\n} from \"~/browser\"\nimport {\n SearchMessageType,\n SearchQueryMessage,\n SearchWorker,\n defaultTransform\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 *\n * @returns Search query observable\n */\nexport function watchSearchQuery(\n el: HTMLInputElement\n): Observable {\n const fn = __search?.transform || defaultTransform\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 )\n .pipe(\n map(() => fn(el.value)),\n startWith(fn(el.value)),\n distinctUntilChanged()\n )\n\n /* Combine into single observable */\n return combineLatest([value$, focus$])\n .pipe(\n map(([value, focus]) => ({ value, focus }))\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$ }: SearchWorker\n): Observable> {\n const internal$ = new Subject()\n\n /* Handle value changes */\n internal$\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 internal$\n .pipe(\n distinctUntilKeyChanged(\"focus\")\n )\n .subscribe(({ focus }) => {\n if (focus) {\n setToggle(\"search\", focus)\n setSearchQueryPlaceholder(el, \"\")\n } else {\n resetSearchQueryPlaceholder(el)\n }\n })\n\n /* Handle reset */\n fromEvent(el.form!, \"reset\")\n .pipe(\n takeUntil(internal$.pipe(takeLast(1)))\n )\n .subscribe(() => setElementFocus(el))\n\n /* Create and return component */\n return watchSearchQuery(el)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 \"~/_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set search query placeholder\n *\n * @param el - Search query element\n * @param value - Placeholder\n */\nexport function setSearchQueryPlaceholder(\n el: HTMLInputElement, value: string\n): void {\n el.placeholder = value\n}\n\n/**\n * Reset search query placeholder\n *\n * @param el - Search query element\n */\nexport function resetSearchQueryPlaceholder(\n el: HTMLInputElement\n): void {\n el.placeholder = translation(\"search.placeholder\")\n}\n","/*\n * Copyright (c) 2016-2021 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 merge,\n of\n} from \"rxjs\"\nimport {\n bufferCount,\n filter,\n finalize,\n map,\n observeOn,\n startWith,\n switchMap,\n tap,\n withLatestFrom,\n zipWith\n} from \"rxjs/operators\"\n\nimport {\n addToSearchResultList,\n resetSearchResultList,\n resetSearchResultMeta,\n setSearchResultMeta\n} from \"~/actions\"\nimport {\n getElementOrThrow,\n watchElementThreshold\n} from \"~/browser\"\nimport {\n SearchResult as SearchResultData,\n SearchWorker,\n isSearchResultMessage\n} from \"~/integrations\"\nimport { renderSearchResult } from \"~/templates\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search result\n */\nexport interface SearchResult {\n data: SearchResultData[] /* Search result data */\n}\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 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 mountSearchResult(\n el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions\n): Observable> {\n const internal$ = new Subject()\n const boundary$ = watchElementThreshold(el.parentElement!)\n .pipe(\n filter(Boolean)\n )\n\n /* Update search result metadata */\n const meta = getElementOrThrow(\":scope > :first-child\", el)\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n withLatestFrom(query$)\n )\n .subscribe(([{ data }, { value }]) => {\n if (value)\n setSearchResultMeta(meta, data.length)\n else\n resetSearchResultMeta(meta)\n })\n\n /* Update search result list */\n const list = getElementOrThrow(\":scope > :last-child\", el)\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n tap(() => resetSearchResultList(list)),\n switchMap(({ data }) => merge(\n of(...data.slice(0, 10)),\n of(...data.slice(10))\n .pipe(\n bufferCount(4),\n zipWith(boundary$),\n switchMap(([chunk]) => of(...chunk))\n )\n ))\n )\n .subscribe(result => {\n addToSearchResultList(list, renderSearchResult(result))\n })\n\n /* Filter search result list */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => ({ data })),\n startWith({ data: [] })\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { round } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set number of search results\n *\n * @param el - Search result metadata element\n * @param value - Number of results\n */\nexport function setSearchResultMeta(\n el: HTMLElement, value: number\n): void {\n switch (value) {\n\n /* No results */\n case 0:\n el.textContent = translation(\"search.result.none\")\n break\n\n /* One result */\n case 1:\n el.textContent = translation(\"search.result.one\")\n break\n\n /* Multiple result */\n default:\n el.textContent = translation(\"search.result.other\", round(value))\n }\n}\n\n/**\n * Reset number of search results\n *\n * @param el - Search result metadata element\n */\nexport function resetSearchResultMeta(\n el: HTMLElement\n): void {\n el.textContent = translation(\"search.result.placeholder\")\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Add an element to the search result list\n *\n * @param el - Search result list element\n * @param child - Search result element\n */\nexport function addToSearchResultList(\n el: HTMLElement, child: Element\n): void {\n el.appendChild(child)\n}\n\n/**\n * Reset search result list\n *\n * @param el - Search result list element\n */\nexport function resetSearchResultList(\n el: HTMLElement\n): void {\n el.innerHTML = \"\"\n}\n","/*\n * Copyright (c) 2016-2021 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 { NEVER, Observable, ObservableInput, merge } from \"rxjs\"\nimport { filter, sample, take } from \"rxjs/operators\"\n\nimport { configuration } from \"~/_\"\nimport {\n Keyboard,\n getActiveElement,\n getElements,\n requestJSON,\n setElementFocus,\n setElementSelection,\n setToggle\n} from \"~/browser\"\nimport {\n SearchIndex,\n isSearchQueryMessage,\n isSearchReadyMessage,\n setupSearchWorker\n} from \"~/integrations\"\n\nimport { Component, getComponentElement } from \"../../_\"\nimport { SearchQuery, mountSearchQuery } from \"../query\"\nimport { SearchResult, mountSearchResult } from \"../result\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search\n */\nexport type Search =\n | SearchQuery\n | SearchResult\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @param url - Search index URL\n *\n * @returns Promise or observable\n */\nfunction fetchSearchIndex(url: string): ObservableInput {\n return __search?.index || requestJSON(url)\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, { keyboard$ }: MountOptions\n): Observable> {\n if (location.protocol === \"file:\")\n return NEVER\n\n /* Set up search worker */\n const config = configuration()\n const worker = setupSearchWorker(config.search, fetchSearchIndex(\n `${config.base}/search/search_index.json`\n ))\n\n /* Retrieve nested 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: prevent form submission */\n case \"Enter\":\n if (active === query)\n key.claim()\n break\n\n /* Escape or Tab: close search */\n case \"Escape\":\n case \"Tab\":\n setToggle(\"search\", false)\n setElementFocus(query, false)\n break\n\n /* Vertical arrows: select previous or next search result */\n case \"ArrowUp\":\n case \"ArrowDown\":\n if (typeof active === \"undefined\") {\n setElementFocus(query)\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 setElementFocus(els[i])\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 setElementFocus(query)\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 setElementFocus(query)\n setElementSelection(query)\n key.claim()\n break\n }\n })\n\n /* Create and return component */\n const query$ = mountSearchQuery(query as HTMLInputElement, worker)\n return merge(\n query$,\n mountSearchResult(result, worker, { query$ })\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set element text selection\n *\n * @param el - Element\n */\nexport function setElementSelection(\n el: HTMLElement\n): void {\n if (el instanceof HTMLInputElement)\n el.select()\n else\n throw new Error(\"Not implemented\")\n}\n","/*\n * Copyright (c) 2016-2021 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 combineLatest\n} from \"rxjs\"\nimport {\n distinctUntilChanged,\n finalize,\n map,\n observeOn,\n tap,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport {\n resetSidebarHeight,\n resetSidebarOffset,\n setSidebarHeight,\n setSidebarOffset\n} from \"~/actions\"\nimport { Viewport } 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 /* User scrolled past header */\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 adjust =\n el.parentElement!.offsetTop -\n el.parentElement!.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 * @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 internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n withLatestFrom(header$)\n )\n .subscribe({\n\n /* Update height and offset */\n next([{ height }, { height: offset }]) {\n setSidebarHeight(el, height)\n setSidebarOffset(el, offset)\n },\n\n /* Reset on complete */\n complete() {\n resetSidebarOffset(el)\n resetSidebarHeight(el)\n }\n })\n\n /* Create and return component */\n return watchSidebar(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set sidebar offset\n *\n * @param el - Sidebar element\n * @param value - Sidebar offset\n */\nexport function setSidebarOffset(\n el: HTMLElement, value: number\n): void {\n el.style.top = `${value}px`\n}\n\n/**\n * Reset sidebar offset\n *\n * @param el - Sidebar element\n */\nexport function resetSidebarOffset(\n el: HTMLElement\n): void {\n el.style.top = \"\"\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Set sidebar height\n *\n * This function doesn't set the height of the actual sidebar, but of its first\n * child – 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 value - Sidebar height\n */\nexport function setSidebarHeight(\n el: HTMLElement, value: number\n): void {\n const scrollwrap = el.firstElementChild as HTMLElement\n scrollwrap.style.height = `${value - 2 * scrollwrap.offsetTop}px`\n}\n\n/**\n * Reset sidebar height\n *\n * @param el - Sidebar element\n */\nexport function resetSidebarHeight(\n el: HTMLElement\n): void {\n const scrollwrap = el.firstElementChild as HTMLElement\n scrollwrap.style.height = \"\"\n}\n","/*\n * Copyright (c) 2016-2021 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 { NEVER, Observable } from \"rxjs\"\n\nimport { fetchSourceFactsFromGitHub } from \"../github\"\nimport { fetchSourceFactsFromGitLab } from \"../gitlab\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository facts\n */\nexport type SourceFacts = string[]\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 NEVER\n }\n}\n","/*\n * Copyright (c) 2016-2021 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 { Observable } from \"rxjs\"\nimport { defaultIfEmpty, map } from \"rxjs/operators\"\n\nimport { requestJSON } from \"~/browser\"\nimport { round } from \"~/utilities\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitHub repository facts\n *\n * @param user - GitHub user\n * @param repo - GitHub repository\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitHub(\n user: string, repo?: string\n): Observable {\n const url = typeof repo !== \"undefined\"\n ? `https://api.github.com/repos/${user}/${repo}`\n : `https://api.github.com/users/${user}`\n return requestJSON(url)\n .pipe(\n map(data => {\n\n /* GitHub repository */\n if (typeof repo !== \"undefined\") {\n const { stargazers_count, forks_count }: Repo = data\n return [\n `${round(stargazers_count!)} Stars`,\n `${round(forks_count!)} Forks`\n ]\n\n /* GitHub user/organization */\n } else {\n const { public_repos }: User = data\n return [\n `${round(public_repos!)} Repositories`\n ]\n }\n }),\n defaultIfEmpty([])\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { Observable } from \"rxjs\"\nimport { defaultIfEmpty, map } from \"rxjs/operators\"\n\nimport { requestJSON } from \"~/browser\"\nimport { round } from \"~/utilities\"\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 `${round(star_count)} Stars`,\n `${round(forks_count)} Forks`\n ])),\n defaultIfEmpty([])\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { NEVER, Observable, Subject, defer, of } from \"rxjs\"\nimport {\n catchError,\n filter,\n finalize,\n map,\n shareReplay,\n tap\n} from \"rxjs/operators\"\n\nimport { setSourceFacts, setSourceState } from \"~/actions\"\nimport { renderSourceFacts } from \"~/templates\"\nimport { hash } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\nimport { SourceFacts, fetchSourceFacts } 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 facts observable\n */\nlet fetch$: Observable\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch repository information\n *\n * This function will try to read the repository facts from session storage,\n * and if unsuccessful, fetch 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 const digest = hash(el.href).toString()\n\n /* Fetch repository facts once */\n return fetch$ ||= defer(() => {\n const data = sessionStorage.getItem(digest)\n if (data) {\n return of(JSON.parse(data))\n } else {\n const value$ = fetchSourceFacts(el.href)\n value$.subscribe(value => {\n try {\n sessionStorage.setItem(digest, JSON.stringify(value))\n } catch (err) {\n /* Uncritical, just swallow */\n }\n })\n\n /* Return value */\n return value$\n }\n })\n .pipe(\n catchError(() => NEVER),\n filter(facts => 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 internal$ = new Subject()\n internal$.subscribe(({ facts }) => {\n setSourceFacts(el, renderSourceFacts(facts))\n setSourceState(el, \"done\")\n })\n\n /* Create and return component */\n return watchSource(el)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 * Set repository facts\n *\n * @param el - Repository element\n * @param child - Repository facts element\n */\nexport function setSourceFacts(\n el: HTMLElement, child: Element\n): void {\n el.lastElementChild!.appendChild(child)\n}\n\n/**\n * Set repository state\n *\n * @param el - Repository element\n * @param state - Repository state\n */\nexport function setSourceState(\n el: HTMLElement, state: \"done\"\n): void {\n el.lastElementChild!.setAttribute(\"data-md-state\", state)\n}\n","/*\n * Copyright (c) 2016-2021 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 } 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 {facts.map(fact => (\n
    • {fact}
    • \n ))}\n
    \n )\n}\n","/*\n * Copyright (c) 2016-2021 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, Subject, animationFrameScheduler } from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n finalize,\n map,\n observeOn,\n tap\n} from \"rxjs/operators\"\n\nimport { resetTabsState, setTabsState } from \"~/actions\"\nimport { Viewport, watchViewportAt } 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 /* User scrolled past tabs */\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 watchViewportAt(el, { header$, viewport$ })\n .pipe(\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 const internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler)\n )\n .subscribe({\n\n /* Update state */\n next({ hidden }) {\n if (hidden)\n setTabsState(el, \"hidden\")\n else\n resetTabsState(el)\n },\n\n /* Reset on complete */\n complete() {\n resetTabsState(el)\n }\n })\n\n /* Create and return component */\n return watchTabs(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 combineLatest\n} from \"rxjs\"\nimport {\n bufferCount,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n observeOn,\n scan,\n startWith,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport {\n resetAnchorActive,\n resetAnchorState,\n setAnchorActive,\n setAnchorState\n} from \"~/actions\"\nimport {\n Viewport,\n getElement,\n getElements,\n watchElementSize\n} from \"~/browser\"\n\nimport { Component } 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}\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 anchors - Anchor elements\n * @param options - Options\n *\n * @returns Table of contents observable\n */\nexport function watchTableOfContents(\n anchors: HTMLAnchorElement[], { viewport$, header$ }: WatchOptions\n): Observable {\n const table = new Map()\n for (const anchor of anchors) {\n const id = decodeURIComponent(anchor.hash.substring(1))\n const target = getElement(`[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 map(header => 24 + header.height)\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 map(() => {\n let path: HTMLAnchorElement[] = []\n return [...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\n /* Re-compute partition when viewport offset changes */\n switchMap(index => combineLatest([adjust$, viewport$])\n .pipe(\n scan(([prev, next], [adjust, { offset: { y } }]) => {\n\n /* Look forward */\n while (next.length) {\n const [, offset] = next[0]\n if (offset - adjust < y) {\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) {\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 /* 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 - Anchor list element\n * @param options - Options\n *\n * @returns Table of contents component observable\n */\nexport function mountTableOfContents(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const internal$ = new Subject()\n internal$\n .pipe(\n observeOn(animationFrameScheduler),\n )\n .subscribe(({ prev, next }) => {\n\n /* Look forward */\n for (const [anchor] of next) {\n resetAnchorActive(anchor)\n resetAnchorState(anchor)\n }\n\n /* Look backward */\n for (const [index, [anchor]] of prev.entries()) {\n setAnchorActive(anchor, index === prev.length - 1)\n setAnchorState(anchor, \"blur\")\n }\n })\n\n /* Create and return component */\n const anchors = getElements(\"[href^=\\\\#]\", el)\n return watchTableOfContents(anchors, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent, of } from \"rxjs\"\nimport {\n filter,\n mapTo,\n mergeMap,\n switchMap,\n tap\n} from \"rxjs/operators\"\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(() => of(...getElements(\"[data-md-scrollfix]\"))),\n tap(el => el.removeAttribute(\"data-md-scrollfix\")),\n filter(isAppleDevice),\n mergeMap(el => fromEvent(el, \"touchstart\")\n .pipe(\n mapTo(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-2021 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 \"focus-visible\"\nimport { Subject, defer, merge } from \"rxjs\"\nimport {\n filter,\n map,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs/operators\"\n\nimport { feature } from \"./_\"\nimport {\n at,\n getElement,\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 mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountSearch,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n setupClipboardJS,\n setupInstantLoading\n} from \"./integrations\"\nimport {\n patchIndeterminate,\n patchScrollfix\n} from \"./patches\"\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 */\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/* 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/* Always close drawer on navigation */\nmerge(location$, target$)\n .subscribe(() => setToggle(\"drawer\", false))\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 = getElement(\"[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 = getElement(\"[href][rel=next]\")\n if (typeof next !== \"undefined\")\n next.click()\n break\n }\n })\n\n/* Set up patches */\npatchIndeterminate({ document$ })\npatchScrollfix({ document$ })\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 /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el as HTMLAnchorElement)),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { target$, viewport$, print$ })),\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 /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, { viewport$, header$ })),\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/* Export to window */\nexport {\n document$,\n location$,\n target$,\n keyboard$,\n viewport$,\n tablet$,\n screen$,\n print$,\n component$\n}\n","/*\n * Copyright (c) 2016-2021 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 { ReplaySubject, Subject, fromEvent } from \"rxjs\"\nimport { mapTo } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch document\n *\n * Documents must be implemented as subjects, so all downstream observables are\n * automatically updated when a new document is emitted. This enabled features\n * like instant loading.\n *\n * @returns Document subject\n */\nexport function watchDocument(): Subject {\n const document$ = new ReplaySubject()\n fromEvent(document, \"DOMContentLoaded\")\n .pipe(\n mapTo(document)\n )\n .subscribe(document$)\n\n /* Return document */\n return document$\n}\n","/*\n * Copyright (c) 2016-2021 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, fromEvent } from \"rxjs\"\nimport { filter, map, share } from \"rxjs/operators\"\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 *\n * @returns Test result\n */\nfunction isSusceptibleToKeyboard(el: HTMLElement): boolean {\n switch (el.tagName) {\n\n /* Form elements */\n case \"INPUT\":\n case \"SELECT\":\n case \"TEXTAREA\":\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 }) => {\n if (mode === \"global\") {\n const active = getActiveElement()\n if (typeof active !== \"undefined\")\n return !isSusceptibleToKeyboard(active)\n }\n return true\n }),\n share()\n )\n}\n","/*\n * Copyright (c) 2016-2021 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 { Observable, Subject } from \"rxjs\"\n\nimport { translation } from \"~/_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n alert$: Subject /* Alert subject */\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 .on(\"success\", ev => subscriber.next(ev))\n })\n .subscribe(() => alert$.next(translation(\"clipboard.copied\")))\n }\n}\n","/*\n * Copyright (c) 2016-2021 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 fromEvent,\n merge,\n of\n} from \"rxjs\"\nimport {\n bufferCount,\n catchError,\n concatMap,\n debounceTime,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n sample,\n share,\n skip,\n skipUntil,\n switchMap\n} from \"rxjs/operators\"\n\nimport { configuration } from \"~/_\"\nimport {\n Viewport,\n ViewportOffset,\n createElement,\n getElement,\n getElements,\n replaceElement,\n request,\n requestXML,\n setLocation,\n setLocationHash,\n setViewportOffset\n} from \"~/browser\"\nimport { getComponentElement } from \"~/components\"\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 * 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 Processed URLs\n */\nfunction preprocess(urls: string[]): string[] {\n if (urls.length < 2)\n return urls\n\n /* Compute references URLs */\n const [root, next] = urls.sort((a, b) => a.length - b.length)\n\n /* Compute common prefix */\n let index = 0\n if (root === next)\n index = root.length\n else\n while (root.charCodeAt(index) === root.charCodeAt(index))\n index++\n\n /* Replace common prefix (i.e. base) with effective base */\n const config = configuration()\n return urls.map(url => (\n url.replace(root.slice(0, index), `${config.base}/`)\n ))\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 = getElement(\"link[rel='shortcut icon']\")\n if (typeof favicon !== \"undefined\")\n favicon.href = favicon.href\n\n /* Intercept internal navigation */\n const push$ = requestXML(`${config.base}/sitemap.xml`)\n .pipe(\n map(sitemap => preprocess(getElements(\"loc\", sitemap)\n .map(node => node.textContent!)\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 HTMLElement) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target && urls.includes(el.href)) {\n ev.preventDefault()\n return of({\n url: new URL(el.href)\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 skip(1),\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.toString())\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 /* 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 setViewportOffset(offset || { y: 0 })\n })\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=header-title]\",\n \"[data-md-component=container]\",\n \"[data-md-component=skip]\"\n ]) {\n const source = getElement(selector)\n const target = getElement(selector, replacement)\n if (\n typeof source !== \"undefined\" &&\n typeof target !== \"undefined\"\n ) {\n replaceElement(source, target)\n }\n }\n })\n\n /* Re-evaluate scripts */\n document$\n .pipe(\n skip(1),\n map(() => getComponentElement(\"container\")),\n switchMap(el => of(...getElements(\"script\", el))),\n concatMap(el => {\n const script = createElement(\"script\")\n if (el.src) {\n script.src = el.src\n replaceElement(el, 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 replaceElement(el, script)\n return EMPTY\n }\n })\n )\n .subscribe()\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 setViewportOffset(offset || { y: 0 })\n })\n}\n","/*\n * Copyright (c) 2016-2021 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 } 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 * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch indeterminate checkboxes\n *\n * This function will replace 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$ }: PatchOptions\n): void {\n document$.subscribe(() => {\n for (const el of getElements(\n \"[data-md-state=indeterminate]\"\n )) {\n el.setAttribute(\"data-md-state\", \"\")\n el.indeterminate = true\n el.checked = false\n }\n })\n}\n","/*\n * Copyright (c) 2016-2021 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} from \"rxjs\"\nimport {\n distinctUntilChanged,\n distinctUntilKeyChanged,\n map,\n switchMap\n} from \"rxjs/operators\"\n\nimport { Viewport, watchElementSize } 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 /* User scrolled past header */\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-2021 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 * Set header state\n *\n * @param el - Header element\n * @param state - Header state\n */\nexport function setHeaderState(\n el: HTMLElement, state: \"shadow\" | \"hidden\"\n): void {\n el.setAttribute(\"data-md-state\", state)\n}\n\n/**\n * Reset header state\n *\n * @param el - Header element\n */\nexport function resetHeaderState(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2021 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 { Viewport, getElements } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { CodeBlock, mountCodeBlock } from \"../code\"\nimport { Details, mountDetails } from \"../details\"\nimport { DataTable, mountDataTable } from \"../table\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content\n */\nexport type Content =\n | CodeBlock\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 viewport$: Observable /* Viewport observable */\n print$: Observable /* 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$, viewport$, print$ }: MountOptions\n): Observable> {\n return merge(\n\n /* Code blocks */\n ...getElements(\"pre > code\", el)\n .map(child => mountCodeBlock(child, { viewport$ })),\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}\n"],"sourceRoot":""} \ No newline at end of file diff --git a/material/assets/manifest.json b/material/assets/manifest.json index 324889bb2..41143e7dd 100644 --- a/material/assets/manifest.json +++ b/material/assets/manifest.json @@ -1,6 +1,6 @@ { - "assets/javascripts/bundle.js": "assets/javascripts/bundle.21e94a31.min.js", - "assets/javascripts/bundle.js.map": "assets/javascripts/bundle.21e94a31.min.js.map", + "assets/javascripts/bundle.js": "assets/javascripts/bundle.9a5a6e7c.min.js", + "assets/javascripts/bundle.js.map": "assets/javascripts/bundle.9a5a6e7c.min.js.map", "assets/javascripts/vendor.js": "assets/javascripts/vendor.00ecb175.min.js", "assets/javascripts/vendor.js.map": "assets/javascripts/vendor.00ecb175.min.js.map", "assets/javascripts/worker/search.js": "assets/javascripts/worker/search.3f4c5856.min.js", diff --git a/material/base.html b/material/base.html index b68d5ea32..906da6577 100644 --- a/material/base.html +++ b/material/base.html @@ -217,7 +217,7 @@ {% endblock %} {% block scripts %} - + {% for path in config["extra_javascript"] %} {% endfor %} diff --git a/src/assets/javascripts/components/content/code/index.ts b/src/assets/javascripts/components/content/code/index.ts index c659d534f..a70eeeeaa 100644 --- a/src/assets/javascripts/components/content/code/index.ts +++ b/src/assets/javascripts/components/content/code/index.ts @@ -21,11 +21,20 @@ */ import ClipboardJS from "clipboard" -import { Observable, Subject } from "rxjs" +import { + NEVER, + Observable, + Subject, + fromEvent, + merge, + of +} from "rxjs" import { distinctUntilKeyChanged, finalize, map, + share, + switchMap, tap, withLatestFrom } from "rxjs/operators" @@ -35,6 +44,7 @@ import { Viewport, getElementContentSize, getElementSize, + getElements, watchMedia } from "~/browser" import { renderClipboardButton } from "~/templates" @@ -86,6 +96,9 @@ let index = 0 /** * Watch code block * + * This function will monitor size changes of the viewport, as well as switches + * of content tabs with embedded code blocks, as both may trigger overflow. + * * @param el - Code block element * @param options - Options * @@ -94,9 +107,27 @@ let index = 0 export function watchCodeBlock( el: HTMLElement, { viewport$ }: WatchOptions ): Observable { - return viewport$ + const container$ = of(el) + .pipe( + switchMap(child => { + const container = child.closest("[data-tabs]") + if (container instanceof HTMLElement) { + return merge( + ...getElements("input", container) + .map(input => fromEvent(input, "change")) + ) + } + return NEVER + }), + share() + ) + + /* Check overflow on resize and tab change */ + return merge( + viewport$.pipe(distinctUntilKeyChanged("size")), + container$ + ) .pipe( - distinctUntilKeyChanged("size"), map(() => { const visible = getElementSize(el) const content = getElementContentSize(el)