{"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/offset/index.ts","webpack:///./src/assets/javascripts/browser/element/size/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/toggle/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/components/_/index.ts","webpack:///./src/assets/javascripts/components/header/_/index.ts","webpack:///./src/assets/javascripts/components/header/react/index.ts","webpack:///./src/assets/javascripts/components/header/set/index.ts","webpack:///./src/assets/javascripts/components/main/_/index.ts","webpack:///./src/assets/javascripts/components/main/react/index.ts","webpack:///./src/assets/javascripts/components/main/set/index.ts","webpack:///./src/assets/javascripts/components/shared/sidebar/set/index.ts","webpack:///./src/assets/javascripts/components/shared/sidebar/react/index.ts","webpack:///./src/assets/javascripts/integrations/search/query/transform/index.ts","webpack:///./src/assets/javascripts/utilities/jsx/index.ts","webpack:///./src/assets/javascripts/utilities/string/index.ts","webpack:///./src/assets/javascripts/integrations/search/worker/message/index.ts","webpack:///./src/assets/javascripts/integrations/search/worker/_/index.ts","webpack:///./src/assets/javascripts/browser/worker/index.ts","webpack:///./src/assets/javascripts/templates/search/index.tsx","webpack:///./src/assets/javascripts/templates/source/index.tsx","webpack:///./src/assets/javascripts/integrations/clipboard/index.ts","webpack:///./src/assets/javascripts/templates/clipboard/index.tsx","webpack:///./src/assets/javascripts/integrations/instant/index.ts","webpack:///./src/assets/javascripts/integrations/keyboard/index.ts","webpack:///./src/assets/javascripts/browser/keyboard/index.ts","webpack:///./src/assets/javascripts/browser/element/select/index.ts","webpack:///./src/assets/javascripts/components/search/query/set/index.ts","webpack:///./src/assets/javascripts/components/search/query/react/index.ts","webpack:///./src/assets/javascripts/components/search/query/_/index.ts","webpack:///./src/assets/javascripts/components/search/reset/_/index.ts","webpack:///./src/assets/javascripts/components/search/reset/react/index.ts","webpack:///./src/assets/javascripts/components/search/result/set/index.ts","webpack:///./src/assets/javascripts/components/search/result/react/index.ts","webpack:///./src/assets/javascripts/components/search/result/_/index.ts","webpack:///./src/assets/javascripts/components/tabs/_/index.ts","webpack:///./src/assets/javascripts/components/tabs/react/index.ts","webpack:///./src/assets/javascripts/components/tabs/set/index.ts","webpack:///./src/assets/javascripts/components/toc/anchor/set/index.ts","webpack:///./src/assets/javascripts/components/toc/_/index.ts","webpack:///./src/assets/javascripts/components/toc/anchor/react/index.ts","webpack:///./src/assets/javascripts/patches/scrollfix/index.ts","webpack:///./src/assets/javascripts/patches/source/index.ts","webpack:///./src/assets/javascripts/patches/source/github/index.ts","webpack:///./src/assets/javascripts/patches/source/gitlab/index.ts","webpack:///./src/assets/javascripts/utilities/rxjs/index.ts","webpack:///./src/assets/javascripts/index.ts","webpack:///./src/assets/javascripts/utilities/config/index.ts","webpack:///./src/assets/javascripts/browser/document/index.ts","webpack:///./src/assets/javascripts/browser/location/base/index.ts","webpack:///./src/assets/javascripts/patches/code/index.ts","webpack:///./src/assets/javascripts/patches/details/index.ts","webpack:///./src/assets/javascripts/patches/script/index.ts","webpack:///./src/assets/javascripts/patches/table/index.ts","webpack:///./src/assets/javascripts/templates/table/index.tsx","webpack:///./src/assets/javascripts/integrations/dialog/index.ts","webpack:///./src/assets/javascripts/components/navigation/index.ts","webpack:///./src/assets/javascripts/components/search/_/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","getElementOffset","x","scrollLeft","y","scrollTop","entry$","Subject","observer$","defer","of","entries","entry","next","pipe","switchMap","resize","merge","finalize","disconnect","shareReplay","bufferSize","refCount","watchElementSize","tap","observer","observe","filter","unobserve","map","contentRect","width","height","startWith","offsetWidth","offsetHeight","getElementSize","isLocalLocation","url","ref","location","host","test","pathname","isAnchorLocation","hash","watchLocation","BehaviorSubject","URL","href","getLocationHash","substring","setLocationHash","addEventListener","ev","stopPropagation","click","watchMedia","query","media","matchMedia","Observable","subscriber","addListener","matches","toggles","drawer","search","setToggle","checked","watchToggle","fromEvent","getViewportOffset","Math","max","pageXOffset","pageYOffset","setViewportOffset","scrollTo","getViewportSize","innerWidth","innerHeight","watchViewportAt","header$","viewport$","size$","distinctUntilKeyChanged","offset$","combineLatest","offsetLeft","offsetTop","offset","size","components$","useComponent","components","distinctUntilChanged","mountHeader","document$","styles","getComputedStyle","includes","position","sticky","watchHeader","type$","main","hx","zipWith","title","observeOn","animationFrame","type","setAttribute","setHeaderTitleActive","removeAttribute","resetHeaderTitleActive","applyHeaderType","header","mountMain","main$","active","setHeaderShadow","resetHeaderShadow","subscribe","noop","adjust$","border$","top","bottom","a","b","watchMain","complete","resetSidebarOffset","style","watchSidebar","adjust","parentElement","min","lock","applySidebar","withLatestFrom","scrollwrap","firstElementChild","setSidebarHeight","setSidebarOffset","sidebar","resetSidebarHeight","defaultTransform","split","terms","index","replace","join","trim","appendChild","child","innerHTML","toString","Node","isArray","h","tag","attributes","children","attr","keys","lang","translate","JSON","parse","textContent","round","toFixed","SearchMessageType","isSearchReadyMessage","message","READY","isSearchQueryMessage","QUERY","isSearchResultMessage","RESULT","setupSearchIndex","config","docs","separator","pipeline","Boolean","setupSearchWorker","index$","base$","worker","Worker","tx$","rx$","throttle","leading","trailing","postMessage","switchMapTo","share","watchWorker","base","SETUP","Flag","renderSearchDocument","flag","parent","PARENT","teaser","TEASER","missing","flat","class","tabIndex","score","text","truncate","renderSearchResult","threshold","Infinity","findIndex","doc","article","best","more","section","renderSource","facts","fact","setupClipboard","dialog$","forEach","block","id","insertBefore","clipboard$","on","clearSelection","mapTo","setupInstantLoading","urls","location$","history","scrollRestoration","favicon","state$","body","metaKey","ctrlKey","closest","preventDefault","push$","pop$","state","prev","ajax$","skip","fetch","credentials","then","res","catchError","setLocation","sample","pushState","dom","DOMParser","response","parseFromString","head","dispatchEvent","CustomEvent","debounceTime","replaceState","bufferCount","setupKeyboard","keyboard$","isContentEditable","isSusceptibleToKeyboard","claim","els","indexOf","HTMLInputElement","Error","select","setElementSelection","resetSearchQueryPlaceholder","placeholder","watchSearchQuery","transform","fn","value$","delay","focus$","watchElementFocus","mountSearchQuery","options","query$","setSearchQueryPlaceholder","applySearchQuery","mountSearchReset","watchSearchReset","addToSearchResultList","applySearchResult","ready$","fetch$","list","meta","setSearchResultMeta","resetSearchResultMeta","thresholds","scan","container","scrollHeight","resetSearchResultList","mountSearchResult","watchElementOffset","mountTabs","screen$","screen","hidden","setTabsHidden","resetTabsHidden","applyTabs","resetAnchorBlur","resetAnchorActive","classList","remove","mountTableOfContents","tablet$","tablet","sidebar$","anchors$","table","Map","decodeURIComponent","set","path","reduce","anchor","pop","reverse","watchAnchorList","toggle","setAnchorActive","setAnchorBlur","applyAnchorList","anchors","isAppleDevice","navigator","userAgent","fetchSourceFacts","match","toLowerCase","user","repo","status","json","stargazers_count","forks_count","public_repos","defaultIfEmpty","fetchSourceFactsFromGitHub","slug","project","encodeURIComponent","star_count","fetchSourceFactsFromGitLab","patchSource","len","charCodeAt","factory","sessionStorage","getItem","setItem","stringify","err","hasAttribute","setScrollLock","resetScrollLock","parseInt","initialize","features","isConfig","SyntaxError","ReplaySubject","watchDocument","take","watchLocationBase","hash$","passive","names","setupComponents","els$","scrollWidth","clientWidth","patchCodeBlocks","details","open","scrollIntoView","patchDetails","concatMap","script","src","onload","patchScripts","sentinel","patchTables","iif","patchScrollfix","duration","dialog","add","setupDialog","navigation$","mountNavigation","toc$","tabs$","search$","reset$","result$","status$","mountSearch","protocol","sort","charAt","link","visibility","values","documentElement"],"mappings":"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","file":"assets/javascripts/bundle.f81dfb4d.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([49,1]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * @return Element or nothing\n */\nexport function getElement<T extends HTMLElement>(\n  selector: string, node: ParentNode = document\n): T | undefined {\n  return node.querySelector<T>(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 * @return Element\n */\nexport function getElementOrThrow<T extends HTMLElement>(\n  selector: string, node: ParentNode = document\n): T {\n  const el = getElement<T>(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 * @return 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 * @return Elements\n */\nexport function getElements<T extends HTMLElement>(\n  selector: string, node: ParentNode = document\n): T[] {\n  return Array.from(node.querySelectorAll<T>(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 * @return Element\n */\nexport function createElement<T extends keyof HTMLElementTagNameMap>(\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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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: boolean = 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 * @return Element focus observable\n */\nexport function watchElementFocus(\n  el: HTMLElement\n): Observable<boolean> {\n  return merge(\n    fromEvent<FocusEvent>(el, \"focus\"),\n    fromEvent<FocusEvent>(el, \"blur\")\n  )\n    .pipe(\n      map(({ type }) => type === \"focus\"),\n      startWith(el === getActiveElement())\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * 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 * @return 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 * @return Element offset observable\n */\nexport function watchElementOffset(\n  el: HTMLElement\n): Observable<ElementOffset> {\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 * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ResizeObserver from \"resize-observer-polyfill\"\nimport {\n  NEVER,\n  Observable,\n  Subject,\n  defer,\n  merge,\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<ResizeObserverEntry>()\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 => merge(of(resize), NEVER)\n      .pipe(\n        finalize(() => resize.disconnect())\n      )\n    ),\n    shareReplay({ bufferSize: 1, refCount: true })\n  )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element size\n *\n * @param el - Element\n *\n * @return Element size\n */\nexport function getElementSize(el: HTMLElement): ElementSize {\n  return {\n    width:  el.offsetWidth,\n    height: el.offsetHeight\n  }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element size\n *\n * This function returns an observable that will subscribe 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 * @return Element size observable\n */\nexport function watchElementSize(\n  el: HTMLElement\n): Observable<ElementSize> {\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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * @return 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 * Check whether a URL is a local link or a file (except `.html`)\n *\n * @param url - URL or HTML anchor element\n * @param ref - Reference URL\n *\n * @return Test result\n */\nexport function isLocalLocation(\n  url: URL | HTMLAnchorElement,\n  ref: URL | Location = location\n): boolean {\n  return url.host === ref.host\n      && /^(?:\\/[\\w-]+)*(?:\\/?|\\.html)$/i.test(url.pathname)\n}\n\n/**\n * Check whether a URL is an anchor link on the current page\n *\n * @param url - URL or HTML anchor element\n * @param ref - Reference URL\n *\n * @return Test result\n */\nexport function isAnchorLocation(\n  url: URL | HTMLAnchorElement,\n  ref: URL | Location = location\n): boolean {\n  return url.pathname === ref.pathname\n      && url.hash.length > 0\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location\n *\n * @return Location subject\n */\nexport function watchLocation(): Subject<URL> {\n  return new BehaviorSubject<URL>(getLocation())\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, startWith } from \"rxjs/operators\"\n\nimport { createElement } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location hash\n *\n * @return 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 * @return Location hash observable\n */\nexport function watchLocationHash(): Observable<string> {\n  return fromEvent<HashChangeEvent>(window, \"hashchange\")\n    .pipe(\n      map(getLocationHash),\n      startWith(getLocationHash()),\n      filter(hash => hash.length > 0),\n      share()\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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\"\nimport { shareReplay, startWith } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch media query\n *\n * @param query - Media query\n *\n * @return Media observable\n */\nexport function watchMedia(query: string): Observable<boolean> {\n  const media = matchMedia(query)\n  return new Observable<boolean>(subscriber => {\n    media.addListener(ev => subscriber.next(ev.matches))\n  })\n    .pipe(\n      startWith(media.matches),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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<Toggle, HTMLInputElement> = {\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 * @return 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 * @return Toggle value observable\n */\nexport function watchToggle(name: Toggle): Observable<boolean> {\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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * @return 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<ViewportOffset>\n): void {\n  window.scrollTo(x || 0, y || 0)\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport offset\n *\n * @return Viewport offset observable\n */\nexport function watchViewportOffset(): Observable<ViewportOffset> {\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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * @return 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 * @return Viewport size observable\n */\nexport function watchViewportSize(): Observable<ViewportSize> {\n  return fromEvent(window, \"resize\", { passive: true })\n    .pipe(\n      map(getViewportSize),\n      startWith(getViewportSize())\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  header$: Observable<Header>          /* Header observable */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport\n *\n * @return Viewport observable\n */\nexport function watchViewport(): Observable<Viewport> {\n  return combineLatest([\n    watchViewportOffset(),\n    watchViewportSize()\n  ])\n    .pipe(\n      map(([offset, size]) => ({ offset, size })),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n}\n\n/**\n * Watch viewport relative to element\n *\n * @param el - Element\n * @param options - Options\n *\n * @return Viewport observable\n */\nexport function watchViewportAt(\n  el: HTMLElement, { header$, viewport$ }: WatchAtOptions\n): Observable<Viewport> {\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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { EMPTY, Observable, of } from \"rxjs\"\nimport {\n  distinctUntilChanged,\n  map,\n  scan,\n  shareReplay,\n  switchMap\n} from \"rxjs/operators\"\n\nimport { getElement, replaceElement } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component\n */\nexport type Component =\n  | \"announce\"                         /* Announcement bar */\n  | \"container\"                        /* Container */\n  | \"header\"                           /* Header */\n  | \"header-title\"                     /* Header title */\n  | \"main\"                             /* Main area */\n  | \"navigation\"                       /* Navigation */\n  | \"search\"                           /* Search */\n  | \"search-query\"                     /* Search input */\n  | \"search-reset\"                     /* Search reset */\n  | \"search-result\"                    /* Search results */\n  | \"skip\"                             /* Skip link */\n  | \"tabs\"                             /* Tabs */\n  | \"toc\"                              /* Table of contents */\n\n/**\n * Component map\n */\nexport type ComponentMap = {\n  [P in Component]?: HTMLElement\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n  document$: Observable<Document>      /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Component map observable\n */\nlet components$: Observable<ComponentMap>\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up bindings to components with given names\n *\n * This function will maintain bindings to the elements identified by the given\n * names in-between document switches and update the elements in-place.\n *\n * @param names - Component names\n * @param options - Options\n */\nexport function setupComponents(\n  names: Component[], { document$ }: WatchOptions\n): void {\n  components$ = document$\n    .pipe(\n\n      /* Build component map */\n      map(document => names.reduce<ComponentMap>((components, name) => {\n        const el = getElement(`[data-md-component=${name}]`, document)\n        return {\n          ...components,\n          ...typeof el !== \"undefined\" ? { [name]: el } : {}\n        }\n      }, {})),\n\n      /* Re-compute component map on document switch */\n      scan((prev, next) => {\n        for (const name of names) {\n          switch (name) {\n\n            /* Top-level components: update */\n            case \"announce\":\n            case \"header-title\":\n            case \"container\":\n            case \"skip\":\n              if (name in prev && typeof prev[name] !== \"undefined\") {\n                replaceElement(prev[name]!, next[name]!)\n                prev[name] = next[name]\n              }\n              break\n\n            /* All other components: rebind */\n            default:\n              if (typeof next[name] !== \"undefined\")\n                prev[name] = getElement(`[data-md-component=${name}]`)\n              else\n                delete prev[name]\n          }\n        }\n        return prev\n      }),\n\n      /* Convert to hot observable */\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n}\n\n/**\n * Retrieve a component\n *\n * The returned observable will only re-emit if the element changed, i.e. if\n * it was replaced from a document which was switched to.\n *\n * @template T - Element type\n *\n * @param name - Component name\n *\n * @return Component observable\n */\nexport function useComponent<T extends HTMLInputElement>(\n  name: \"search-query\"\n): Observable<T>\nexport function useComponent<T extends HTMLElement>(\n  name: Component\n): Observable<T>\nexport function useComponent<T extends HTMLElement>(\n  name: Component\n): Observable<T> {\n  return components$\n    .pipe(\n      switchMap(components => (\n        typeof components[name] !== \"undefined\"\n          ? of(components[name] as T)\n          : EMPTY\n      )),\n      distinctUntilChanged()\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, OperatorFunction, combineLatest, pipe } from \"rxjs\"\nimport {\n  distinctUntilChanged,\n  filter,\n  map,\n  startWith,\n  switchMap,\n  zipWith\n} from \"rxjs/operators\"\n\nimport {\n  Viewport,\n  getElement,\n  watchViewportAt\n} from \"browser\"\n\nimport { useComponent } from \"../../_\"\nimport {\n  applyHeaderType,\n  watchHeader\n} from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header type\n */\nexport type HeaderType =\n  | \"site\"                             /* Header shows site title */\n  | \"page\"                             /* Header shows page title */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface Header {\n  type: HeaderType                     /* Header type */\n  sticky: boolean                      /* Header stickyness */\n  height: number                       /* Header visible height */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  document$: Observable<Document>      /* Document observable */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount header from source observable\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountHeader(\n  { document$, viewport$ }: MountOptions\n): OperatorFunction<HTMLElement, Header> {\n  return pipe(\n    switchMap(el => {\n      const header$ = watchHeader(el, { document$ })\n\n      /* Compute whether the header should switch to page header */\n      const type$ = useComponent(\"main\")\n        .pipe(\n          map(main => getElement(\"h1, h2, h3, h4, h5, h6\", main)!),\n          filter(hx => typeof hx !== \"undefined\"),\n          zipWith(useComponent(\"header-title\")),\n          switchMap(([hx, title]) => watchViewportAt(hx, { header$, viewport$ })\n            .pipe(\n              map(({ offset: { y } }) => {\n                return y >= hx.offsetHeight ? \"page\" : \"site\"\n              }),\n              distinctUntilChanged(),\n              applyHeaderType(title)\n            )\n          ),\n          startWith<HeaderType>(\"site\")\n        )\n\n      /* Combine into single observable */\n      return combineLatest([header$, type$])\n        .pipe(\n          map(([header, type]): Header => ({ type, ...header }))\n        )\n    })\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  MonoTypeOperatorFunction,\n  Observable,\n  animationFrameScheduler,\n  of,\n  pipe\n} from \"rxjs\"\nimport {\n  distinctUntilChanged,\n  finalize,\n  map,\n  observeOn,\n  shareReplay,\n  switchMap,\n  tap\n} from \"rxjs/operators\"\n\nimport { watchElementSize } from \"browser\"\n\nimport { Header, HeaderType } from \"../_\"\nimport {\n  resetHeaderTitleActive,\n  setHeaderTitleActive\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n  document$: Observable<Document>      /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header\n *\n * @param el - Header element\n *\n * @return Header observable\n */\nexport function watchHeader(\n  el: HTMLElement, { document$ }: WatchOptions\n): Observable<Omit<Header, \"type\">> {\n  return document$\n    .pipe(\n      map(() => {\n        const styles = getComputedStyle(el)\n        return [\n          \"sticky\",                    /* Modern browsers */\n          \"-webkit-sticky\"             /* Safari */\n        ].includes(styles.position)\n      }),\n      distinctUntilChanged(),\n      switchMap(sticky => {\n        if (sticky) {\n          return watchElementSize(el)\n            .pipe(\n              map(({ height }) => ({\n                sticky: true,\n                height\n              }))\n            )\n        } else {\n          return of({\n            sticky: false,\n            height: 0\n          })\n        }\n      }),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Apply header title type\n *\n * @param el - Header title element\n *\n * @return Operator function\n */\nexport function applyHeaderType(\n  el: HTMLElement\n): MonoTypeOperatorFunction<HeaderType> {\n  return pipe(\n\n    /* Defer repaint to next animation frame */\n    observeOn(animationFrameScheduler),\n    tap(type => {\n      setHeaderTitleActive(el, type === \"page\")\n    }),\n\n    /* Reset on complete or error */\n    finalize(() => {\n      resetHeaderTitleActive(el)\n    })\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 active\n *\n * @param el - Header title element\n * @param value - Whether the title is shown\n */\nexport function setHeaderTitleActive(\n  el: HTMLElement, value: boolean\n): void {\n  el.setAttribute(\"data-md-state\", value ? \"active\" : \"\")\n}\n\n/**\n * Reset header title active\n *\n * @param el - Header title element\n */\nexport function resetHeaderTitleActive(\n  el: HTMLElement\n): void {\n  el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  OperatorFunction,\n  Subject,\n  noop,\n  pipe\n} from \"rxjs\"\nimport {\n  distinctUntilKeyChanged,\n  finalize,\n  switchMap,\n  tap\n} from \"rxjs/operators\"\n\nimport { Viewport } from \"browser\"\n\nimport { useComponent } from \"../../_\"\nimport { Header } from \"../../header\"\nimport {\n  applyHeaderShadow,\n  watchMain\n} from \"../react\"\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                      /* Scrolled past top offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  header$: Observable<Header>          /* Header observable */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount main area from source observable\n *\n * The header must be connected to the main area observable outside of the\n * operator function, as the header will persist in-between document switches\n * while the main area is replaced. However, the header observable must be\n * passed to this function, so we connect both via a long-living subject.\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountMain(\n  { header$, viewport$ }: MountOptions\n): OperatorFunction<HTMLElement, Main> {\n  const main$ = new Subject<Main>()\n\n  /* Connect to main area observable via long-living subject */\n  useComponent(\"header\")\n    .pipe(\n      switchMap(header => main$\n        .pipe(\n          distinctUntilKeyChanged(\"active\"),\n          applyHeaderShadow(header)\n        )\n      )\n    )\n      .subscribe(noop)\n\n  /* Return operator */\n  return pipe(\n    switchMap(el => watchMain(el, { header$, viewport$ })),\n    tap(main => main$.next(main)),\n    finalize(() => main$.complete())\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  MonoTypeOperatorFunction,\n  Observable,\n  animationFrameScheduler,\n  combineLatest,\n  pipe\n} from \"rxjs\"\nimport {\n  distinctUntilChanged,\n  distinctUntilKeyChanged,\n  finalize,\n  map,\n  observeOn,\n  switchMap,\n  tap\n} from \"rxjs/operators\"\n\nimport { Viewport, watchElementSize } from \"browser\"\n\nimport { Header } from \"../../header\"\nimport { Main } from \"../_\"\nimport {\n  resetHeaderShadow,\n  setHeaderShadow\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n  header$: Observable<Header>          /* Header observable */\n  viewport$: Observable<Viewport>      /* Viewport 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 * @return Main area observable\n */\nexport function watchMain(\n  el: HTMLElement, { header$, viewport$ }: WatchOptions\n): Observable<Main> {\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<Main>((a, b) => {\n        return a.offset === b.offset\n            && a.height === b.height\n            && a.active === b.active\n      })\n    )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Apply header shadow\n *\n * @param el - Header element\n *\n * @return Operator function\n */\nexport function applyHeaderShadow(\n  el: HTMLElement\n): MonoTypeOperatorFunction<Main> {\n  return pipe(\n\n    /* Defer repaint to next animation frame */\n    observeOn(animationFrameScheduler),\n    tap(({ active }) => {\n      setHeaderShadow(el, active)\n    }),\n\n    /* Reset on complete or error */\n    finalize(() => {\n      resetHeaderShadow(el)\n    })\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 shadow\n *\n * @param el - Header element\n * @param value - Whether the shadow is shown\n */\nexport function setHeaderShadow(\n  el: HTMLElement, value: boolean\n): void {\n  el.setAttribute(\"data-md-state\", value ? \"shadow\" : \"\")\n}\n\n/**\n * Reset header shadow\n *\n * @param el - Header element\n */\nexport function resetHeaderShadow(\n  el: HTMLElement\n): void {\n  el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, which greatly\n * reduced 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 to slowly.\n *\n * By setting the height of the sidebar to zero (while preserving `padding`),\n * and the height on its first element, this behaviour can be mitigiated. We\n * must assume that the top- and bottom offset (`padding`) are equal, as the\n * `offsetBottom` value is `undefined`.\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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  MonoTypeOperatorFunction,\n  Observable,\n  animationFrameScheduler,\n  combineLatest,\n  pipe\n} from \"rxjs\"\nimport {\n  distinctUntilChanged,\n  finalize,\n  map,\n  observeOn,\n  tap,\n  withLatestFrom\n} from \"rxjs/operators\"\n\nimport { Viewport } from \"browser\"\n\nimport { Header } from \"../../../header\"\nimport { Main } from \"../../../main\"\nimport { Sidebar } from \"../_\"\nimport {\n  resetSidebarHeight,\n  resetSidebarOffset,\n  setSidebarHeight,\n  setSidebarOffset\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n  main$: Observable<Main>              /* Main area observable */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n}\n\n/**\n * Apply options\n */\ninterface ApplyOptions {\n  header$: Observable<Header>          /* Header 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 * @return Sidebar observable\n */\nexport function watchSidebar(\n  el: HTMLElement, { main$, viewport$ }: WatchOptions\n): Observable<Sidebar> {\n  const adjust = 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          lock: y >= offset + adjust\n        }\n      }),\n      distinctUntilChanged<Sidebar>((a, b) => {\n        return a.height === b.height\n            && a.lock   === b.lock\n      })\n    )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Apply sidebar\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @return Operator function\n */\nexport function applySidebar(\n  el: HTMLElement, { header$ }: ApplyOptions\n): MonoTypeOperatorFunction<Sidebar> {\n  return pipe(\n\n    /* Defer repaint to next animation frame */\n    observeOn(animationFrameScheduler),\n    withLatestFrom(header$),\n    tap(([{ height, lock }, { height: offset }]) => {\n      setSidebarHeight(el, height)\n\n      /* Set offset in locked state depending on header height */\n      if (lock)\n        setSidebarOffset(el, offset)\n      else\n        resetSidebarOffset(el)\n    }),\n\n    /* Re-map to sidebar */\n    map(([sidebar]) => sidebar),\n\n    /* Reset on complete or error */\n    finalize(() => {\n      resetSidebarOffset(el)\n      resetSidebarHeight(el)\n    })\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * @return 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 * @return 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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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// tslint:disable no-null-keyword\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<string, any>\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 * @return 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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Translation keys\n */\ntype TranslateKey =\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 * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Translations\n */\nlet lang: Record<string, string>\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Translate the given key\n *\n * @param key - Key to be translated\n * @param value - Value to be replaced\n *\n * @return Translation\n */\nexport function translate(\n  key: TranslateKey, value?: string | number\n): string {\n  if (typeof lang === \"undefined\") {\n    const el = getElementOrThrow(\"#__lang\")\n    lang = JSON.parse(el.textContent!)\n  }\n  if (typeof lang[key] === \"undefined\") {\n    throw new ReferenceError(`Invalid translation: ${key}`)\n  }\n  return typeof value !== \"undefined\"\n    ? lang[key].replace(\"#\", value.toString())\n    : lang[key]\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 * @return 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); // tslint:disable-line\n    return `${value.substring(0, i)}...`\n  }\n  return value\n}\n\n/**\n * Round a number for display with source 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 * @return 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 * @return 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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * @return 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 * @return 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 * @return 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 * @return 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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 { Observable, Subject, asyncScheduler } from \"rxjs\"\nimport {\n  map,\n  observeOn,\n  share,\n  withLatestFrom\n} from \"rxjs/operators\"\n\nimport { WorkerHandler, watchWorker } from \"browser\"\nimport { translate } from \"utilities\"\n\nimport { SearchIndex, SearchIndexPipeline } from \"../../_\"\nimport {\n  SearchMessage,\n  SearchMessageType,\n  SearchSetupMessage,\n  isSearchResultMessage\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n  index$: Observable<SearchIndex>      /* Search index observable */\n  base$: Observable<string>            /* Location base observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search index\n *\n * @param data - Search index\n *\n * @return 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 = [translate(\"search.config.lang\")]\n\n  /* Override default separator with value from translation */\n  if (config.separator === \"[\\\\s\\\\-]+\")\n    config.separator = translate(\"search.config.separator\")\n\n  /* Set pipeline from translation */\n  const pipeline = translate(\"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 * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search web 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 options - Options\n *\n * @return Worker handler\n */\nexport function setupSearchWorker(\n  url: string, { index$, base$ }: SetupOptions\n): WorkerHandler<SearchMessage> {\n  const worker = new Worker(url)\n\n  /* Create communication channels and resolve relative links */\n  const tx$ = new Subject<SearchMessage>()\n  const rx$ = watchWorker(worker, { tx$ })\n    .pipe(\n      withLatestFrom(base$),\n      map(([message, base]) => {\n        if (isSearchResultMessage(message)) {\n          for (const result of message.data)\n            for (const document of result)\n              document.location = `${base}/${document.location}`\n        }\n        return message\n      }),\n      share()\n    )\n\n  /* Set up search index */\n  index$\n    .pipe(\n      map<SearchIndex, SearchSetupMessage>(data => ({\n        type: SearchMessageType.SETUP,\n        data: setupSearchIndex(data)\n      })),\n      observeOn(asyncScheduler)\n    )\n      .subscribe(tx$.next.bind(tx$))\n\n  /* Return worker handler */\n  return { tx$, rx$ }\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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<T>                      /* Message transmission subject */\n  rx$: Observable<T>                   /* 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<T extends WorkerMessage> {\n  tx$: Observable<T>                   /* Message transmission observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch a web worker\n *\n * This function returns an observable that will send 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 * @return Worker message observable\n */\nexport function watchWorker<T extends WorkerMessage>(\n  worker: Worker, { tx$ }: WatchOptions<T>\n): Observable<T> {\n\n  /* Intercept messages from worker-like objects */\n  const rx$ = fromEvent<MessageEvent>(worker, \"message\")\n    .pipe<T>(\n      map(({ data }) => data)\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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  SearchDocument,\n  SearchMetadata,\n  SearchResult\n} from \"integrations/search\"\nimport { h, translate, 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 section - Search document\n * @param flag - Render flags\n *\n * @return Element\n */\nfunction renderSearchDocument(\n  document: SearchDocument & SearchMetadata, flag: Flag\n) {\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 => [<del>{key}</del>, \" \"])\n    .flat()\n    .slice(0, -1)\n\n  /* Render article or section, depending on flags */\n  const url = document.location\n  return (\n    <a href={url} class=\"md-search-result__link\" tabIndex={-1}>\n      <article\n        class={[\"md-search-result__article\", ...parent\n          ? [\"md-search-result__article--document\"]\n          : []\n        ].join(\" \")}\n        data-md-score={document.score.toFixed(2)}\n      >\n        {parent > 0 && <div class=\"md-search-result__icon md-icon\"></div>}\n        <h1 class=\"md-search-result__title\">{document.title}</h1>\n        {teaser > 0 && document.text.length > 0 &&\n          <p class=\"md-search-result__teaser\">\n            {truncate(document.text, 320)}\n          </p>\n        }\n        {teaser > 0 && missing.length > 0 &&\n          <p class=\"md-search-result__terms\">\n            {translate(\"search.result.term.missing\")}: {...missing}\n          </p>\n        }\n      </article>\n    </a>\n  )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search result\n *\n * @param result - Search result\n * @param threshold - Score threshold\n *\n * @return Element\n */\nexport function renderSearchResult(\n  result: SearchResult, threshold: number = Infinity\n) {\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      <details class=\"md-search-result__more\">\n        <summary tabIndex={-1}>\n          {more.length > 0 && more.length === 1\n            ? translate(\"search.result.more.one\")\n            : translate(\"search.result.more.other\", more.length)\n          }\n        </summary>\n        {...more.map(section => renderSearchDocument(section, Flag.TEASER))}\n      </details>\n    ] : []\n  ]\n\n  /* Render search result */\n  return (\n    <li class=\"md-search-result__item\">\n      {children}\n    </li>\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 \"patches/source\"\nimport { h } from \"utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render source facts\n *\n * @param facts - Source facts\n *\n * @return Element\n */\nexport function renderSource(\n  facts: SourceFacts\n) {\n  return (\n    <ul class=\"md-source__facts\">\n      {facts.map(fact => (\n        <li class=\"md-source__fact\">{fact}</li>\n      ))}\n    </ul>\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * as ClipboardJS from \"clipboard\"\nimport { NEVER, Observable, Subject } from \"rxjs\"\nimport { mapTo, share, tap } from \"rxjs/operators\"\n\nimport { getElements } from \"browser\"\nimport { renderClipboardButton } from \"templates\"\nimport { translate } from \"utilities\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n  document$: Observable<Document>      /* Document observable */\n  dialog$: Subject<string>             /* Dialog subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up clipboard\n *\n * This function implements the Clipboard.js integration and injects a button\n * into all code blocks when the document changes.\n *\n * @param options - Options\n *\n * @return Clipboard observable\n */\nexport function setupClipboard(\n  { document$, dialog$ }: SetupOptions\n): Observable<ClipboardJS.Event> {\n  if (!ClipboardJS.isSupported())\n    return NEVER\n\n  /* Inject 'copy-to-clipboard' buttons */\n  document$.subscribe(() => {\n    const blocks = getElements(\"pre > code\")\n    blocks.forEach((block, index) => {\n      const parent = block.parentElement!\n      parent.id = `__code_${index}`\n      parent.insertBefore(\n        renderClipboardButton(parent.id),\n        block\n      )\n    })\n  })\n\n  /* Initialize clipboard */\n  const clipboard$ = new Observable<ClipboardJS.Event>(subscriber => {\n    new ClipboardJS(\".md-clipboard\").on(\"success\", ev => subscriber.next(ev))\n  })\n    .pipe(\n      share()\n    )\n\n  /* Display notification for clipboard event */\n  clipboard$\n    .pipe(\n      tap(ev => ev.clearSelection()),\n      mapTo(translate(\"clipboard.copied\"))\n    )\n      .subscribe(dialog$)\n\n  /* Return clipboard */\n  return clipboard$\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, translate } from \"utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a 'copy-to-clipboard' button\n *\n * @param id - Unique identifier\n *\n * @return Element\n */\nexport function renderClipboardButton(id: string) {\n  return (\n    <button\n      class=\"md-clipboard md-icon\"\n      title={translate(\"clipboard.copy\")}\n      data-clipboard-target={`#${id} > code`}\n    ></button>\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, from, fromEvent, merge, of } from \"rxjs\"\nimport {\n  bufferCount,\n  catchError,\n  debounceTime,\n  distinctUntilChanged,\n  distinctUntilKeyChanged,\n  filter,\n  map,\n  sample,\n  share,\n  skip,\n  switchMap\n} from \"rxjs/operators\"\n\nimport {\n  Viewport,\n  ViewportOffset,\n  getElement,\n  isAnchorLocation,\n  isLocalLocation,\n  replaceElement,\n  setLocation,\n  setLocationHash,\n  setToggle,\n  setViewportOffset\n} from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * History state\n */\ninterface State {\n  url: URL                             /* State URL */\n  offset?: ViewportOffset              /* State viewport offset */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n  document$: Subject<Document>         /* Document subject */\n  location$: Subject<URL>              /* Location subject */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up instant loading\n *\n * When fetching, theoretically, we could use `responseType: \"document\"`, but\n * since all MkDocs links are relative, we need to make sure that the current\n * location matches the document we just loaded. Otherwise any relative links\n * in the document could use the old location.\n *\n * This is the reason why we need to synchronize history events and the process\n * of fetching the document for navigation changes (except `popstate` events):\n *\n * 1. Fetch document via `XMLHTTPRequest`\n * 2. Set new location via `history.pushState`\n * 3. Parse and emit fetched document\n *\n * For `popstate` events, we must not use `history.pushState`, or the forward\n * history will be irreversibly overwritten. In case the request fails, the\n * location change is dispatched regularly.\n *\n * @param options - Options\n */\nexport function setupInstantLoading(\n  urls: string[], { document$, viewport$, location$ }: SetupOptions\n): void {\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  /* Hack: ensure absolute favicon link to omit 404s on document switch */\n  const favicon = getElement<HTMLLinkElement>(`link[rel=\"shortcut icon\"]`)\n  if (typeof favicon !== \"undefined\")\n    favicon.href = favicon.href // tslint:disable-line no-self-assignment\n\n  /* Intercept link clicks and convert to state change */\n  const state$ = fromEvent<MouseEvent>(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 (\n            el && !el.target &&\n            isLocalLocation(el) &&\n            urls.includes(el.href)\n          ) {\n            if (!isAnchorLocation(el))\n              ev.preventDefault()\n            return of(el)\n          }\n        }\n        return NEVER\n      }),\n      map(el => ({ url: new URL(el.href) })),\n      share<State>()\n    )\n\n  /* Always close search on link click */\n  state$.subscribe(() => {\n    setToggle(\"search\", false)\n  })\n\n  /* Filter state changes to dispatch */\n  const push$ = state$\n    .pipe(\n      filter(({ url }) => !isAnchorLocation(url)),\n      share()\n    )\n\n  /* Intercept popstate events (history back and forward) */\n  const pop$ = fromEvent<PopStateEvent>(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<State>()\n    )\n\n  /* Emit location change */\n  merge(push$, pop$)\n    .pipe(\n      distinctUntilChanged((prev, next) => prev.url.href === next.url.href),\n      map(({ url }) => url)\n    )\n      .subscribe(location$)\n\n  /* Fetch document on location change */\n  const ajax$ = location$\n    .pipe(\n      distinctUntilKeyChanged(\"pathname\"),\n      skip(1),\n      switchMap(url => from(fetch(url.href, {\n        credentials: \"same-origin\"\n      }).then(res => res.text()))\n        .pipe(\n          catchError(() => {\n            setLocation(url)\n            return NEVER\n          })\n        )\n      ),\n      share()\n    )\n\n  /* Set new location as soon as the document was fetched */\n  push$\n    .pipe(\n      sample(ajax$)\n    )\n      .subscribe(({ url }) => {\n        history.pushState({}, \"\", url.toString())\n      })\n\n  /* Parse and emit document */\n  const dom = new DOMParser()\n  ajax$\n    .pipe(\n      map(response => dom.parseFromString(response, \"text/html\"))\n    )\n      .subscribe(document$)\n\n  /* Intercept instant loading */\n  const instant$ = merge(push$, pop$)\n    .pipe(\n      sample(document$)\n    )\n\n  // TODO: this must be combined with search scroll restoration on mobile\n  instant$.subscribe(({ url, offset }) => {\n    if (url.hash && !offset) {\n      setLocationHash(url.hash)\n    } else {\n      setViewportOffset(offset || { y: 0 })\n    }\n  })\n\n  /* Replace document metadata */\n  document$\n    .pipe(\n      skip(1) // Skip initial\n    )\n      .subscribe(({ title, head }) => {\n        document.title = title\n\n        /* Replace meta tags */\n        for (const selector of [\n          `link[rel=\"canonical\"]`,\n          `meta[name=\"author\"]`,\n          `meta[name=\"description\"]`\n        ]) {\n          const next = getElement(selector, head)\n          const prev = getElement(selector, document.head)\n          if (\n            typeof next !== \"undefined\" &&\n            typeof prev !== \"undefined\"\n          ) {\n            replaceElement(prev, next)\n          }\n        }\n\n        /* Finished, dispatch document switch event */\n        document.dispatchEvent(new CustomEvent(\"DOMContentSwitch\"))\n      })\n\n  /* Debounce update of viewport offset */\n  viewport$\n    .pipe(\n      debounceTime(250),\n      distinctUntilKeyChanged(\"offset\")\n    )\n      .subscribe(({ offset }) => {\n        history.replaceState(offset, \"\")\n      })\n\n  /* Set viewport offset from history */\n  merge(state$, pop$)\n    .pipe(\n      bufferCount(2, 1),\n      filter(([prev, next]) => {\n        return prev.url.pathname === next.url.pathname\n            && !isAnchorLocation(next.url)\n      }),\n      map(([, state]) => state)\n    )\n      .subscribe(({ offset }) => {\n        setViewportOffset(offset || { y: 0 })\n      })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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\"\nimport {\n  filter,\n  map,\n  share,\n  withLatestFrom\n} from \"rxjs/operators\"\n\nimport {\n  Key,\n  getActiveElement,\n  getElement,\n  getElements,\n  getToggle,\n  isSusceptibleToKeyboard,\n  setElementFocus,\n  setElementSelection,\n  setToggle,\n  watchKeyboard\n} from \"browser\"\nimport { useComponent } from \"components\"\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 extends Key {\n  mode: KeyboardMode                   /* Keyboard mode */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up keyboard\n *\n * This function will set up the keyboard handlers and ensure that keys are\n * correctly propagated. Currently there are two modes:\n *\n * - `global`: This mode is active when the search is closed. It is intended\n *   to assign hotkeys to specific functions of the site. Currently the search,\n *   previous and next page can be triggered.\n *\n * - `search`: This mode is active when the search is open. It maps certain\n *   navigational keys to offer search results that can be entirely navigated\n *   through keyboard input.\n *\n * The keyboard observable is returned and can be used to monitor the keyboard\n * in order toassign further hotkeys to custom functions.\n *\n * @return Keyboard observable\n */\nexport function setupKeyboard(): Observable<Keyboard> {\n  const keyboard$ = watchKeyboard()\n    .pipe(\n      map<Key, Keyboard>(key => ({\n        mode: getToggle(\"search\") ? \"search\" : \"global\",\n        ...key\n      })),\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  /* Set up search keyboard handlers */\n  keyboard$\n    .pipe(\n      filter(({ mode }) => mode === \"search\"),\n      withLatestFrom(\n        useComponent(\"search-query\"),\n        useComponent(\"search-result\")\n      )\n    )\n      .subscribe(([key, query, result]) => {\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      withLatestFrom(useComponent(\"search-query\"))\n    )\n      .subscribe(([key, query]) => {\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          /* 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  /* Return keyboard */\n  return keyboard$\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Key\n */\nexport interface Key {\n  type: string                         /* Key type */\n  claim(): void                        /* Key claim */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether an element may receive keyboard input\n *\n * @param el - Element\n *\n * @return Test result\n */\nexport function 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\n/**\n * Watch keyboard\n *\n * @return Keyboard observable\n */\nexport function watchKeyboard(): Observable<Key> {\n  return fromEvent<KeyboardEvent>(window, \"keydown\")\n    .pipe(\n      filter(ev => !(ev.metaKey || ev.ctrlKey)),\n      map(ev => ({\n        type: ev.key,\n        claim() {\n          ev.preventDefault()\n          ev.stopPropagation()\n        }\n      })),\n      share()\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 { translate } from \"utilities\"\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 = translate(\"search.placeholder\")\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  MonoTypeOperatorFunction,\n  Observable,\n  combineLatest,\n  fromEvent,\n  merge,\n  pipe\n} from \"rxjs\"\nimport {\n  delay,\n  distinctUntilChanged,\n  finalize,\n  map,\n  startWith,\n  tap\n} from \"rxjs/operators\"\n\nimport { watchElementFocus } from \"browser\"\nimport { SearchTransformFn, defaultTransform } from \"integrations\"\n\nimport { SearchQuery } from \"../_\"\nimport {\n  resetSearchQueryPlaceholder,\n  setSearchQueryPlaceholder\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n  transform?: SearchTransformFn        /* Transformation function */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch search query\n *\n * Note that the focus event which triggers re-reading the current query value\n * is delayed by `1ms` so the input's empty state is allowed to propagate.\n *\n * @param el - Search query element\n * @param options - Options\n *\n * @return Search query observable\n */\nexport function watchSearchQuery(\n  el: HTMLInputElement, { transform }: WatchOptions = {}\n): Observable<SearchQuery> {\n  const fn = transform || defaultTransform\n\n  /* Intercept keyboard events */\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  /* Intercept focus events */\n  const focus$ = watchElementFocus(el)\n\n  /* Combine into single observable */\n  return combineLatest([value$, focus$])\n    .pipe(\n      map(([value, focus]) => ({ value, focus }))\n    )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Apply search query\n *\n * @param el - Search query element\n *\n * @return Operator function\n */\nexport function applySearchQuery(\n  el: HTMLInputElement\n): MonoTypeOperatorFunction<SearchQuery> {\n  return pipe(\n\n    /* Hide placeholder when search is focused */\n    tap(({ focus }) => {\n      if (focus) {\n        setSearchQueryPlaceholder(el, \"\")\n      } else {\n        resetSearchQueryPlaceholder(el)\n      }\n    }),\n\n    /* Reset on complete or error */\n    finalize(() => {\n      resetSearchQueryPlaceholder(el)\n    })\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 { OperatorFunction, pipe } from \"rxjs\"\nimport {\n  distinctUntilKeyChanged,\n  map,\n  switchMap\n} from \"rxjs/operators\"\n\nimport { WorkerHandler, setToggle } from \"browser\"\nimport {\n  SearchMessage,\n  SearchMessageType,\n  SearchQueryMessage,\n  SearchTransformFn\n} from \"integrations\"\n\nimport {\n  applySearchQuery,\n  watchSearchQuery\n} from \"../react\"\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 * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  transform?: SearchTransformFn        /* Transformation function */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search query from source observable\n *\n * @param handler - Worker handler\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountSearchQuery(\n  { tx$ }: WorkerHandler<SearchMessage>, options: MountOptions = {}\n): OperatorFunction<HTMLInputElement, SearchQuery> {\n  return pipe(\n    switchMap(el => {\n      const query$ = watchSearchQuery(el, options)\n\n      /* Subscribe worker to search query */\n      query$\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      /* Toggle search on focus */\n      query$\n        .pipe(\n          distinctUntilKeyChanged(\"focus\")\n        )\n          .subscribe(({ focus }) => {\n            if (focus)\n              setToggle(\"search\", focus)\n          })\n\n      /* Return search query */\n      return query$\n        .pipe(\n          applySearchQuery(el)\n        )\n    })\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 { OperatorFunction, pipe } from \"rxjs\"\nimport {\n  mapTo,\n  startWith,\n  switchMap,\n  switchMapTo,\n  tap\n} from \"rxjs/operators\"\n\nimport { setElementFocus } from \"browser\"\n\nimport { useComponent } from \"../../../_\"\nimport { watchSearchReset } from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search reset from source observable\n *\n * @return Operator function\n */\nexport function mountSearchReset(): OperatorFunction<HTMLElement, void> {\n  return pipe(\n    switchMap(el => watchSearchReset(el)\n      .pipe(\n        switchMapTo(useComponent(\"search-query\")),\n        tap(setElementFocus),\n        mapTo(undefined)\n      )\n    ),\n    startWith(undefined)\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 { mapTo } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch search reset\n *\n * @param el - Search reset element\n *\n * @return Search reset observable\n */\nexport function watchSearchReset(\n  el: HTMLElement\n): Observable<void> {\n  return fromEvent(el, \"click\")\n    .pipe(\n      mapTo(undefined)\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 { translate } 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 = translate(\"search.result.none\")\n      break\n\n    /* One result */\n    case 1:\n      el.textContent = translate(\"search.result.one\")\n      break\n\n    /* Multiple result */\n    default:\n      el.textContent = translate(\"search.result.other\", 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 = translate(\"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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  MonoTypeOperatorFunction,\n  Observable,\n  animationFrameScheduler,\n  pipe\n} from \"rxjs\"\nimport {\n  finalize,\n  map,\n  mapTo,\n  observeOn,\n  scan,\n  switchMap,\n  withLatestFrom\n} from \"rxjs/operators\"\n\nimport { getElementOrThrow } from \"browser\"\nimport { SearchResult } from \"integrations/search\"\nimport { renderSearchResult } from \"templates\"\n\nimport { SearchQuery } from \"../../query\"\nimport {\n  addToSearchResultList,\n  resetSearchResultList,\n  resetSearchResultMeta,\n  setSearchResultMeta\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Apply options\n */\ninterface ApplyOptions {\n  query$: Observable<SearchQuery>     /* Search query observable */\n  ready$: Observable<boolean>         /* Search ready observable */\n  fetch$: Observable<boolean>         /* Result fetch observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Apply search results\n *\n * This function will perform a lazy rendering of the search results, depending\n * on the vertical offset of the search result container. When the scroll offset\n * reaches the bottom of the element, more results are fetched and rendered.\n *\n * @param el - Search result element\n * @param options - Options\n *\n * @return Operator function\n */\nexport function applySearchResult(\n  el: HTMLElement, { query$, ready$, fetch$ }: ApplyOptions\n): MonoTypeOperatorFunction<SearchResult[]> {\n  const list = getElementOrThrow(\".md-search-result__list\", el)\n  const meta = getElementOrThrow(\".md-search-result__meta\", el)\n  return pipe(\n\n    /* Apply search result metadata */\n    withLatestFrom(query$, ready$),\n    map(([result, query]) => {\n      if (query.value) {\n        setSearchResultMeta(meta, result.length)\n      } else {\n        resetSearchResultMeta(meta)\n      }\n      return result\n    }),\n\n    /* Apply search result list */\n    switchMap(result => {\n      const thresholds = [...result.map(([best]) => best.score), 0]\n      return fetch$\n        .pipe(\n\n          /* Defer repaint to next animation frame */\n          observeOn(animationFrameScheduler),\n          scan(index => {\n            const container = el.parentElement!\n            while (index < result.length) {\n              addToSearchResultList(list, renderSearchResult(\n                result[index++], thresholds[index]\n              ))\n              if (container.scrollHeight - container.offsetHeight > 16)\n                break\n            }\n            return index\n          }, 0),\n\n          /* Re-map to search result */\n          mapTo(result),\n\n          /* Reset on complete or error */\n          finalize(() => {\n            resetSearchResultList(list)\n          })\n        )\n      }\n    )\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, OperatorFunction, pipe } from \"rxjs\"\nimport {\n  distinctUntilChanged,\n  filter,\n  map,\n  mapTo,\n  startWith,\n  switchMap\n} from \"rxjs/operators\"\n\nimport { WorkerHandler, watchElementOffset } from \"browser\"\nimport {\n  SearchMessage,\n  SearchResult,\n  isSearchReadyMessage,\n  isSearchResultMessage\n} from \"integrations\"\n\nimport { SearchQuery } from \"../../query\"\nimport { applySearchResult } from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  query$: Observable<SearchQuery>      /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search result from source observable\n *\n * @param handler - Worker handler\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountSearchResult(\n  { rx$ }: WorkerHandler<SearchMessage>, { query$ }: MountOptions\n): OperatorFunction<HTMLElement, SearchResult[]> {\n  return pipe(\n    switchMap(el => {\n      const container = el.parentElement!\n\n      /* Compute if search is ready */\n      const ready$ = rx$\n        .pipe(\n          filter(isSearchReadyMessage),\n          mapTo(true)\n        )\n\n      /* Compute whether there are more search results to fetch */\n      const fetch$ = watchElementOffset(container)\n        .pipe(\n          map(({ y }) => {\n            return y >= container.scrollHeight - container.offsetHeight - 16\n          }),\n          distinctUntilChanged(),\n          filter(Boolean)\n        )\n\n      /* Apply search results */\n      return rx$\n        .pipe(\n          filter(isSearchResultMessage),\n          map(({ data }) => data),\n          applySearchResult(el, { query$, ready$, fetch$ }),\n          startWith([])\n        )\n    })\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, OperatorFunction, of, pipe } from \"rxjs\"\nimport {\n  distinctUntilKeyChanged,\n  map,\n  switchMap\n} from \"rxjs/operators\"\n\nimport { Viewport, watchViewportAt } from \"browser\"\n\nimport { Header } from \"../../header\"\nimport { applyTabs } from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Tabs\n */\nexport interface Tabs {\n  hidden: boolean                      /* Whether the tabs are hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  header$: Observable<Header>          /* Header observable */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n  screen$: Observable<boolean>         /* Media screen observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount tabs from source observable\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountTabs(\n  { header$, viewport$, screen$ }: MountOptions\n): OperatorFunction<HTMLElement, Tabs> {\n  return pipe(\n    switchMap(el => screen$\n      .pipe(\n        switchMap(screen => {\n\n          /* [screen +]: Mount tabs above screen breakpoint */\n          if (screen) {\n            return watchViewportAt(el, { header$, viewport$ })\n              .pipe(\n                map(({ offset: { y } }) => ({ hidden: y >= 10 })),\n                distinctUntilKeyChanged(\"hidden\"),\n                applyTabs(el)\n              )\n\n          /* [screen -]: Unmount tabs below screen breakpoint */\n          } else {\n            return of({ hidden: true })\n          }\n        })\n      )\n    )\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  MonoTypeOperatorFunction,\n  animationFrameScheduler,\n  pipe\n} from \"rxjs\"\nimport { finalize, observeOn, tap } from \"rxjs/operators\"\n\nimport { Tabs } from \"../_\"\nimport {\n  resetTabsHidden,\n  setTabsHidden\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Apply tabs\n *\n * @param el - Tabs element\n *\n * @return Operator function\n */\nexport function applyTabs(\n  el: HTMLElement\n): MonoTypeOperatorFunction<Tabs> {\n  return pipe(\n\n    /* Defer repaint to next animation frame */\n    observeOn(animationFrameScheduler),\n    tap(({ hidden }) => {\n      setTabsHidden(el, hidden)\n    }),\n\n    /* Reset on complete or error */\n    finalize(() => {\n      resetTabsHidden(el)\n    })\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 hidden\n *\n * @param el - Tabs element\n * @param value - Whether the element is hidden\n */\nexport function setTabsHidden(\n  el: HTMLElement, value: boolean\n): void {\n  el.setAttribute(\"data-md-state\", value ? \"hidden\" : \"\")\n}\n\n/**\n * Reset tabs hidden\n *\n * @param el - Tabs element\n */\nexport function resetTabsHidden(\n  el: HTMLElement\n): void {\n  el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 blur\n *\n * @param el - Anchor element\n * @param value - Whether the anchor is blurred\n */\nexport function setAnchorBlur(\n  el: HTMLElement, value: boolean\n): void {\n  el.setAttribute(\"data-md-state\", value ? \"blur\" : \"\")\n}\n\n/**\n * Reset anchor blur\n *\n * @param el - Anchor element\n */\nexport function resetAnchorBlur(\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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  OperatorFunction,\n  combineLatest,\n  of,\n  pipe\n} from \"rxjs\"\nimport { map, switchMap } from \"rxjs/operators\"\n\nimport { Viewport, getElements } from \"browser\"\n\nimport { Header } from \"../../header\"\nimport { Main } from \"../../main\"\nimport {\n  Sidebar,\n  applySidebar,\n  watchSidebar\n} from \"../../shared\"\nimport {\n  AnchorList,\n  applyAnchorList,\n  watchAnchorList\n} from \"../anchor\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Table of contents for [tablet -]\n */\ninterface TableOfContentsBelowTablet {} // tslint:disable-line\n\n/**\n * Table of contents for [tablet +]\n */\ninterface TableOfContentsAboveTablet {\n  sidebar: Sidebar                     /* Sidebar */\n  anchors: AnchorList                  /* Anchor list */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Table of contents\n */\nexport type TableOfContents =\n  | TableOfContentsBelowTablet\n  | TableOfContentsAboveTablet\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  header$: Observable<Header>          /* Header observable */\n  main$: Observable<Main>              /* Main area observable */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n  tablet$: Observable<boolean>         /* Tablet media observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount table of contents from source observable\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountTableOfContents(\n  { header$, main$, viewport$, tablet$ }: MountOptions\n): OperatorFunction<HTMLElement, TableOfContents> {\n  return pipe(\n    switchMap(el => tablet$\n      .pipe(\n        switchMap(tablet => {\n\n          /* [tablet +]: Mount table of contents in sidebar */\n          if (tablet) {\n            const els = getElements<HTMLAnchorElement>(\".md-nav__link\", el)\n\n            /* Watch and apply sidebar */\n            const sidebar$ = watchSidebar(el, { main$, viewport$ })\n              .pipe(\n                applySidebar(el, { header$ })\n              )\n\n            /* Watch and apply anchor list (scroll spy) */\n            const anchors$ = watchAnchorList(els, { header$, viewport$ })\n              .pipe(\n                applyAnchorList(els)\n              )\n\n            /* Combine into single hot observable */\n            return combineLatest([sidebar$, anchors$])\n              .pipe(\n                map(([sidebar, anchors]) => ({ sidebar, anchors }))\n              )\n\n          /* [tablet -]: Unmount table of contents */\n          } else {\n            return of({})\n          }\n        })\n      )\n    )\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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  MonoTypeOperatorFunction,\n  Observable,\n  animationFrameScheduler,\n  combineLatest,\n  pipe\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 { Viewport, getElement, watchElementSize } from \"browser\"\n\nimport { Header } from \"../../../header\"\nimport { AnchorList } from \"../_\"\nimport {\n  resetAnchorActive,\n  resetAnchorBlur,\n  setAnchorActive,\n  setAnchorBlur\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n  header$: Observable<Header>          /* Header observable */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch anchor list\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 anchor list needs\n * 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 els - Anchor elements\n * @param options - Options\n *\n * @return Anchor list observable\n */\nexport function watchAnchorList(\n  els: HTMLAnchorElement[], { header$, viewport$ }: WatchOptions\n): Observable<AnchorList> {\n  const table = new Map<HTMLAnchorElement, HTMLElement>()\n  for (const el of els) {\n    const id = decodeURIComponent(el.hash.substring(1))\n    const target = getElement(`[id=\"${id}\"]`)\n    if (typeof target !== \"undefined\")\n      table.set(el, target)\n  }\n\n  /* Compute necessary adjustment for header */\n  const adjust$ = header$\n    .pipe(\n      map(header => 18 + 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<HTMLAnchorElement[], number>())\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            return 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 * Apply anchor list\n *\n * @param els - Anchor elements\n *\n * @return Operator function\n */\nexport function applyAnchorList(\n  els: HTMLAnchorElement[]\n): MonoTypeOperatorFunction<AnchorList> {\n  return pipe(\n\n    /* Defer repaint to next animation frame */\n    observeOn(animationFrameScheduler),\n    tap(({ prev, next }) => {\n\n      /* Look forward */\n      for (const [el] of next) {\n        resetAnchorActive(el)\n        resetAnchorBlur(el)\n      }\n\n      /* Look backward */\n      prev.forEach(([el], index) => {\n        setAnchorActive(el, index === prev.length - 1)\n        setAnchorBlur(el, true)\n      })\n    }),\n\n    /* Reset on complete or error */\n    finalize(() => {\n      for (const el of els) {\n        resetAnchorActive(el)\n        resetAnchorBlur(el)\n      }\n    })\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, iif, merge } from \"rxjs\"\nimport { map, mapTo, shareReplay, switchMap } 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>      /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether the given device is an Apple device\n *\n * @return 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  const els$ = document$\n    .pipe(\n      map(() => getElements(\"[data-md-scrollfix]\")),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n\n  /* Remove marker attribute, so we'll only add the fix once */\n  els$.subscribe(els => {\n    for (const el of els)\n      el.removeAttribute(\"data-md-scrollfix\")\n  })\n\n  /* Patch overflow scrolling on touch start */\n  iif(isAppleDevice, els$, NEVER)\n    .pipe(\n      switchMap(els => merge(...els.map(el => (\n        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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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\"\nimport { catchError, filter, map, switchMap } from \"rxjs/operators\"\n\nimport { getElementOrThrow, getElements } from \"browser\"\nimport { renderSource } from \"templates\"\nimport { cache, hash } from \"utilities\"\n\nimport { fetchSourceFactsFromGitHub } from \"./github\"\nimport { fetchSourceFactsFromGitLab } from \"./gitlab\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Source facts\n */\nexport type SourceFacts = string[]\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n  document$: Observable<Document>      /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch source facts\n *\n * @param url - Source repository URL\n *\n * @return Source facts observable\n */\nfunction fetchSourceFacts(\n  url: string\n): Observable<SourceFacts> {\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/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch elements containing repository information\n *\n * This function will retrieve the URL from the repository link and try to\n * query data from integrated source code platforms like GitHub or GitLab.\n *\n * @param options - Options\n */\nexport function patchSource(\n  { document$ }: PatchOptions\n): void {\n  document$\n    .pipe(\n      map(() => getElementOrThrow<HTMLAnchorElement>(\".md-source[href]\")),\n      switchMap(({ href }) => (\n        cache(`${hash(href)}`, () => fetchSourceFacts(href))\n      )),\n      filter(facts => facts.length > 0),\n      catchError(() => NEVER)\n    )\n      .subscribe(facts => {\n        for (const el of getElements(\".md-source__repository\")) {\n          if (!el.hasAttribute(\"data-md-state\")) {\n            el.setAttribute(\"data-md-state\", \"done\")\n            el.appendChild(renderSource(facts))\n          }\n        }\n      })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 } from \"rxjs\"\nimport {\n  defaultIfEmpty,\n  filter,\n  map,\n  share,\n  switchMap\n} from \"rxjs/operators\"\n\nimport { round } from \"utilities\"\n\nimport { SourceFacts } from \"..\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitHub source facts\n *\n * @param user - GitHub user\n * @param repo - GitHub repository\n *\n * @return Source facts observable\n */\nexport function fetchSourceFactsFromGitHub(\n  user: string, repo?: string\n): Observable<SourceFacts> {\n  const url = typeof repo !== \"undefined\"\n    ? `https://api.github.com/repos/${user}/${repo}`\n    : `https://api.github.com/users/${user}`\n  return from(fetch(url))\n    .pipe(\n      filter(res => res.status === 200),\n      switchMap(res => res.json()),\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      share()\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 } from \"rxjs\"\nimport {\n  defaultIfEmpty,\n  filter,\n  map,\n  share,\n  switchMap\n} from \"rxjs/operators\"\n\nimport { round } from \"utilities\"\n\nimport { SourceFacts } from \"..\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitLab source facts\n *\n * @param base - GitLab base\n * @param project - GitLab project\n *\n * @return Source facts observable\n */\nexport function fetchSourceFactsFromGitLab(\n  base: string, project: string\n): Observable<SourceFacts> {\n  const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}`\n  return from(fetch(url))\n    .pipe(\n      filter(res => res.status === 200),\n      switchMap(res => res.json()),\n      map(({ star_count, forks_count }: ProjectSchema) => ([\n        `${round(star_count)} Stars`,\n        `${round(forks_count)} Forks`\n      ])),\n      defaultIfEmpty([]),\n      share()\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, defer, of } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Cache the last value emitted by an observable in session storage\n *\n * If the key is not found in session storage, the factory is executed and the\n * latest value emitted will automatically be persisted to sessions storage.\n * Note that the values emitted by the returned observable must be serializable\n * as `JSON`, or data will be lost.\n *\n * @template T - Value type\n *\n * @param key - Cache key\n * @param factory - Observable factory\n *\n * @return Value observable\n */\nexport function cache<T>(\n  key: string, factory: () => Observable<T>\n): Observable<T> {\n  return defer(() => {\n    const data = sessionStorage.getItem(key)\n    if (data) {\n      return of(JSON.parse(data) as T)\n\n    /* Retrieve value from observable factory and write to storage */\n    } else {\n      const value$ = factory()\n      value$.subscribe(value => {\n        try {\n          sessionStorage.setItem(key, JSON.stringify(value))\n        } catch (err) {\n          /* Uncritical, just swallow */\n        }\n      })\n\n      /* Return value */\n      return value$\n    }\n  })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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// DISCLAIMER: this file is still WIP. There're some refactoring opportunities\n// which must be tackled after we gathered some feedback on v5.\n// tslint:disable\n\nimport \"focus-visible\"\n\nimport {\n  merge,\n  combineLatest,\n  animationFrameScheduler,\n  fromEvent,\n  from,\n  defer,\n  of,\n  NEVER\n} from \"rxjs\"\nimport {\n  delay,\n  switchMap,\n  tap,\n  filter,\n  withLatestFrom,\n  observeOn,\n  take,\n  shareReplay,\n  catchError,\n  map\n} from \"rxjs/operators\"\n\nimport {\n  watchToggle,\n  setToggle,\n  getElements,\n  watchMedia,\n  watchDocument,\n  watchLocation,\n  watchLocationHash,\n  watchViewport,\n  isLocalLocation,\n  setLocationHash,\n  watchLocationBase\n} from \"browser\"\nimport {\n  mountHeader,\n  mountMain,\n  mountNavigation,\n  mountSearch,\n  mountTableOfContents,\n  mountTabs,\n  useComponent,\n  setupComponents,\n  mountSearchQuery,\n  mountSearchReset,\n  mountSearchResult\n} from \"components\"\nimport {\n  setupClipboard,\n  setupDialog,\n  setupKeyboard,\n  setupInstantLoading,\n  setupSearchWorker,\n  SearchIndex,\n  SearchIndexPipeline\n} from \"integrations\"\nimport {\n  patchCodeBlocks,\n  patchTables,\n  patchDetails,\n  patchScrollfix,\n  patchSource,\n  patchScripts\n} from \"patches\"\nimport { isConfig } from \"utilities\"\n\n/* ------------------------------------------------------------------------- */\n\n/* Denote that JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Test for iOS */\nif (navigator.userAgent.match(/(iPad|iPhone|iPod)/g))\n  document.documentElement.classList.add(\"ios\")\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/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Initialize Material for MkDocs\n *\n * @param config - Configuration\n */\nexport function initialize(config: unknown) {\n  if (!isConfig(config))\n    throw new SyntaxError(`Invalid configuration: ${JSON.stringify(config)}`)\n\n  /* Set up subjects */\n  const document$ = watchDocument()\n  const location$ = watchLocation()\n\n  /* Set up user interface observables */\n  const base$     = watchLocationBase(config.base, { location$ })\n  const hash$     = watchLocationHash()\n  const viewport$ = watchViewport()\n  const tablet$   = watchMedia(\"(min-width: 960px)\")\n  const screen$   = watchMedia(\"(min-width: 1220px)\")\n\n  /* ----------------------------------------------------------------------- */\n\n  /* Set up component bindings */\n  setupComponents([\n    \"announce\",                        /* Announcement bar */\n    \"container\",                       /* Container */\n    \"header\",                          /* Header */\n    \"header-title\",                    /* Header title */\n    \"main\",                            /* Main area */\n    \"navigation\",                      /* Navigation */\n    \"search\",                          /* Search */\n    \"search-query\",                    /* Search input */\n    \"search-reset\",                    /* Search reset */\n    \"search-result\",                   /* Search results */\n    \"skip\",                            /* Skip link */\n    \"tabs\",                            /* Tabs */\n    \"toc\"                              /* Table of contents */\n  ], { document$ })\n\n  const keyboard$ = setupKeyboard()\n\n  // Hack: only make code blocks focusable on non-touch devices\n  if (matchMedia(\"(hover)\").matches)\n    patchCodeBlocks({ document$, viewport$ })\n  patchDetails({ document$, hash$ })\n  patchScripts({ document$ })\n  patchSource({ document$ })\n  patchTables({ document$ })\n\n  /* Force 1px scroll offset to trigger overflow scrolling */\n  patchScrollfix({ document$ })\n\n  /* Set up clipboard and dialog */\n  const dialog$ = setupDialog()\n  const clipboard$ = setupClipboard({ document$, dialog$ })\n\n  /* ----------------------------------------------------------------------- */\n\n  /* Create header observable */\n  const header$ = useComponent(\"header\")\n    .pipe(\n      mountHeader({ document$, viewport$ }),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n\n  const main$ = useComponent(\"main\")\n    .pipe(\n      mountMain({ header$, viewport$ }),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n\n  /* ----------------------------------------------------------------------- */\n\n  const navigation$ = useComponent(\"navigation\")\n    .pipe(\n      mountNavigation({ header$, main$, viewport$, screen$ }),\n      shareReplay({ bufferSize: 1, refCount: true }) // shareReplay because there might be late subscribers\n    )\n\n  const toc$ = useComponent(\"toc\")\n    .pipe(\n      mountTableOfContents({ header$, main$, viewport$, tablet$ }),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n\n  const tabs$ = useComponent(\"tabs\")\n    .pipe(\n      mountTabs({ header$, viewport$, screen$ }),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n\n  /* ----------------------------------------------------------------------- */\n\n  /* Search worker - only if search is present */\n  const worker$ = useComponent(\"search\")\n    .pipe(\n      switchMap(() => defer(() => {\n        const index = config.search && config.search.index\n          ? config.search.index\n          : undefined\n\n        /* Fetch index if it wasn't passed explicitly */\n        const index$ = (\n          typeof index !== \"undefined\"\n            ? from(index)\n            : base$\n                .pipe(\n                  switchMap(base => fetch(`${base}/search/search_index.json`, {\n                    credentials: \"same-origin\"\n                  }).then(res => res.json())) // SearchIndex\n                )\n        )\n\n        return of(setupSearchWorker(config.search.worker, {\n          base$, index$\n        }))\n      }))\n    )\n\n  /* ----------------------------------------------------------------------- */\n\n  /* Mount search query */\n  const search$ = worker$\n    .pipe(\n      switchMap(worker => {\n\n        const query$ = useComponent(\"search-query\")\n          .pipe(\n            mountSearchQuery(worker, { transform: config.search.transform }),\n            shareReplay({ bufferSize: 1, refCount: true })\n          )\n\n        /* Mount search reset */\n        const reset$ = useComponent(\"search-reset\")\n          .pipe(\n            mountSearchReset(),\n            shareReplay({ bufferSize: 1, refCount: true })\n          )\n\n        /* Mount search result */\n        const result$ = useComponent(\"search-result\")\n          .pipe(\n            mountSearchResult(worker, { query$ }),\n            shareReplay({ bufferSize: 1, refCount: true })\n          )\n\n        return useComponent(\"search\")\n          .pipe(\n            mountSearch(worker, { query$, reset$, result$ }),\n          )\n      }),\n      catchError(() => {\n        useComponent(\"search\")\n          .subscribe(el => el.hidden = true) // TODO: Hack\n        return NEVER\n      }),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n\n  /* ----------------------------------------------------------------------- */\n\n  // // put into search...\n  hash$\n    .pipe(\n      tap(() => setToggle(\"search\", false)),\n      delay(125), // ensure that it runs after the body scroll reset...\n    )\n      .subscribe(hash => setLocationHash(`#${hash}`))\n\n  // TODO: scroll restoration must be centralized\n  combineLatest([\n    watchToggle(\"search\"),\n    tablet$,\n  ])\n    .pipe(\n      withLatestFrom(viewport$),\n      switchMap(([[toggle, tablet], { offset: { y }}]) => {\n        const active = toggle && !tablet\n        return document$\n          .pipe(\n            delay(active ? 400 : 100),\n            observeOn(animationFrameScheduler),\n            tap(({ body }) => active\n              ? setScrollLock(body, y)\n              : resetScrollLock(body)\n            )\n          )\n      })\n    )\n      .subscribe()\n\n  /* ----------------------------------------------------------------------- */\n\n  /* Always close drawer on click */\n  fromEvent<MouseEvent>(document.body, \"click\")\n    .pipe(\n      filter(ev => !(ev.metaKey || ev.ctrlKey)),\n      filter(ev => {\n        if (ev.target instanceof HTMLElement) {\n          const el = ev.target.closest(\"a\") // TODO: abstract as link click?\n          if (el && isLocalLocation(el)) {\n            return true\n          }\n        }\n        return false\n      })\n    )\n      .subscribe(() => {\n        setToggle(\"drawer\", false)\n      })\n\n  /* Enable instant loading, if not on file:// protocol */\n  if (\n    config.features.includes(\"navigation.instant\") &&\n    location.protocol !== \"file:\"\n  ) {\n    const dom = new DOMParser()\n\n    /* Fetch sitemap and extract URL whitelist */\n    base$\n      .pipe(\n        switchMap(base => from(fetch(`${base}/sitemap.xml`)\n          .then(res => res.text())\n          .then(text => dom.parseFromString(text, \"text/xml\"))\n        )),\n        withLatestFrom(base$),\n        map(([document, base]) => {\n          const urls = getElements(\"loc\", document)\n            .map(node => node.textContent!)\n\n          // Hack: This is a temporary fix to normalize instant loading lookup\n          // on localhost and Netlify previews. If this approach proves to be\n          // suitable, we'll refactor URL whitelisting anyway. We take the two\n          // shortest URLs and determine the common prefix to isolate the\n          // domain. If there're no two domains, we just leave it as-is, as\n          // there isn't anything to be loaded anway.\n          if (urls.length > 1) {\n            const [a, b] = urls.sort((a, b) => a.length - b.length)\n\n            /* Determine common prefix */\n            let index = 0\n            if (a === b)\n              index = a.length\n            else\n              while (a.charAt(index) === b.charAt(index))\n                index++\n\n            /* Replace common prefix (i.e. base) with effective base */\n            for (let i = 0; i < urls.length; i++)\n              urls[i] = urls[i].replace(a.slice(0, index), `${base}/`)\n          }\n          return urls\n        })\n      )\n        .subscribe(urls => {\n          setupInstantLoading(urls, { document$, location$, viewport$ })\n        })\n  }\n\n  /* ----------------------------------------------------------------------- */\n\n  /* Unhide permalinks on first tab */\n  keyboard$\n    .pipe(\n      filter(key => key.mode === \"global\" && key.type === \"Tab\"),\n      take(1)\n    )\n      .subscribe(() => {\n        for (const link of getElements(\".headerlink\"))\n          link.style.visibility = \"visible\"\n      })\n\n  /* ----------------------------------------------------------------------- */\n\n  const state = {\n\n    /* Browser observables */\n    document$,\n    location$,\n    viewport$,\n\n    /* Component observables */\n    header$,\n    main$,\n    navigation$,\n    search$,\n    tabs$,\n    toc$,\n\n    /* Integration observables */\n    clipboard$,\n    keyboard$,\n    dialog$\n  }\n\n  /* Subscribe to all observables */\n  merge(...Object.values(state))\n    .subscribe()\n  return state\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 { SearchIndex, SearchTransformFn } from \"integrations\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flags\n */\nexport type Feature =\n  | \"navigation.tabs\"                  /* Tabs navigation */\n  | \"navigation.instant\"               /* Instant loading */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Configuration\n */\nexport interface Config {\n  base: string                         /* Base URL */\n  features: Feature[]                  /* Feature flags */\n  search: {\n    worker: string                     /* Worker URL */\n    index?: Promise<SearchIndex>       /* Promise resolving with index */\n    transform?: SearchTransformFn      /* Transformation function */\n  }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Ensure that the given value is a valid configuration\n *\n * We could use `jsonschema` or any other schema validation framework, but that\n * would just add more bloat to the bundle, so we'll keep it plain and simple.\n *\n * @param config - Configuration\n *\n * @return Test result\n */\nexport function isConfig(config: any): config is Config {\n  return typeof config === \"object\"\n      && typeof config.base === \"string\"\n      && typeof config.features === \"object\"\n      && typeof config.search === \"object\"\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * @return Document subject\n */\nexport function watchDocument(): Subject<Document> {\n  const document$ = new ReplaySubject<Document>()\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-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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\"\nimport { map, shareReplay, take } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n  location$: Observable<URL>           /* Location observable */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location base\n *\n * @return Location base observable\n */\nexport function watchLocationBase(\n  base: string, { location$ }: WatchOptions\n): Observable<string> {\n  return location$\n    .pipe(\n      take(1),\n      map(({ href }) => new URL(base, href)\n        .toString()\n        .replace(/\\/$/, \"\")\n      ),\n      shareReplay({ bufferSize: 1, refCount: true })\n    )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 { distinctUntilKeyChanged, map } from \"rxjs/operators\"\n\nimport { Viewport, getElements } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  document$: Observable<Document>      /* Document observable */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all `code` elements\n *\n * This function will make overflowing code blocks focusable via keyboard, so\n * they can be scrolled without a mouse.\n *\n * @param options - Options\n */\nexport function patchCodeBlocks(\n  { document$, viewport$ }: MountOptions\n): void {\n  const els$ = document$\n    .pipe(\n      map(() => getElements<HTMLTableElement>(\"pre > code\"))\n    )\n\n  /* Observe viewport size only */\n  const size$ = viewport$\n    .pipe(\n      distinctUntilKeyChanged(\"size\")\n    )\n\n  /* Make overflowing elements focusable */\n  combineLatest([els$, size$])\n    .subscribe(([els]) => {\n      for (const el of els) {\n        if (el.scrollWidth > el.clientWidth)\n          el.setAttribute(\"tabindex\", \"0\")\n        else\n          el.removeAttribute(\"tabindex\")\n      }\n    })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 {\n  filter,\n  map,\n  switchMapTo,\n  tap\n} from \"rxjs/operators\"\n\nimport {\n  getElement,\n  getElements,\n  watchMedia\n} from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n  document$: Observable<Document>      /* Document observable */\n  hash$: Observable<string>            /* Location hash observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all `details` elements\n *\n * This function will ensure that all `details` tags are opened prior to\n * printing, so the whole content of the page is included, and on anchor jumps.\n *\n * @param options - Options\n */\nexport function patchDetails(\n  { document$, hash$ }: PatchOptions\n): void {\n  const els$ = document$\n    .pipe(\n      map(() => getElements<HTMLDetailsElement>(\"details\"))\n    )\n\n  /* Open all details before printing */\n  merge(\n    watchMedia(\"print\").pipe(filter(Boolean)),  /* Webkit */\n    fromEvent(window, \"beforeprint\")            /* IE, FF */\n  )\n    .pipe(\n      switchMapTo(els$)\n    )\n      .subscribe(els => {\n        for (const el of els)\n          el.setAttribute(\"open\", \"\")\n      })\n\n  /* Open parent details and fix anchor jump */\n  hash$\n    .pipe(\n      map(id => getElement(`[id=\"${id}\"]`)!),\n      filter(el => typeof el !== \"undefined\"),\n      tap(el => {\n        const details = el.closest(\"details\")\n        if (details && !details.open)\n          details.setAttribute(\"open\", \"\")\n      })\n    )\n      .subscribe(el => el.scrollIntoView())\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { EMPTY, Observable, noop, of } from \"rxjs\"\nimport {\n  concatMap,\n  map,\n  skip,\n  switchMap,\n  withLatestFrom\n} from \"rxjs/operators\"\n\nimport {\n  createElement,\n  getElements,\n  replaceElement\n} from \"browser\"\nimport { useComponent } from \"components\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n  document$: Observable<Document>      /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all `script` elements\n *\n * This function must be run after a document switch, which means the first\n * emission must be ignored.\n *\n * @param options - Options\n */\nexport function patchScripts(\n  { document$ }: PatchOptions\n): void {\n  const els$ = document$\n    .pipe(\n      skip(1),\n      withLatestFrom(useComponent(\"container\")),\n      map(([, el]) => getElements<HTMLScriptElement>(\"script\", el))\n    )\n\n  /* Evaluate all scripts via replacement in order */\n  els$\n    .pipe(\n      switchMap(els => of(...els)),\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(noop)\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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\"\nimport { map } from \"rxjs/operators\"\n\nimport {\n  createElement,\n  getElements,\n  replaceElement\n} from \"browser\"\nimport { renderTable } from \"templates\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  document$: Observable<Document>      /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all `table` elements\n *\n * This function will re-render all tables by wrapping them to improve overflow\n * scrolling on smaller screen sizes.\n *\n * @param options - Options\n */\nexport function patchTables(\n  { document$ }: MountOptions\n): void {\n  const sentinel = createElement(\"table\")\n  document$\n    .pipe(\n      map(() => getElements<HTMLTableElement>(\"table:not([class])\"))\n    )\n      .subscribe(els => {\n        for (const el of els) {\n          replaceElement(el, sentinel)\n          replaceElement(sentinel, renderTable(el))\n        }\n      })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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 * @return Element\n */\nexport function renderTable(\n  table: HTMLTableElement\n) {\n  return (\n    <div class=\"md-typeset__scrollwrap\">\n      <div class=\"md-typeset__table\">\n        {table}\n      </div>\n    </div>\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Subject, animationFrameScheduler, noop, of } from \"rxjs\"\nimport {\n  delay,\n  map,\n  observeOn,\n  switchMap,\n  tap\n} from \"rxjs/operators\"\n\nimport { createElement } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n  duration?: number                    /* Display duration (default: 2s) */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up dialog\n *\n * @param options - Options\n *\n * @return Dialog observable\n */\nexport function setupDialog(\n  { duration }: SetupOptions = {}\n): Subject<string> {\n  const dialog$ = new Subject<string>()\n\n  /* Create dialog */\n  const dialog = createElement(\"div\")                                           // TODO: improve scoping\n  dialog.classList.add(\"md-dialog\", \"md-typeset\")\n\n  /* Display dialog */\n  dialog$\n    .pipe(\n      switchMap(text => of(document.body) // useComponent(\"container\")\n        .pipe(\n          map(container => container.appendChild(dialog)),\n          observeOn(animationFrameScheduler),\n          delay(1), // Strangley it doesnt work when we push things to the new animation frame...\n          tap(el => {\n            el.innerHTML = text\n            el.setAttribute(\"data-md-state\", \"open\")\n          }),\n          delay(duration || 2000),\n          tap(el => el.removeAttribute(\"data-md-state\")),\n          delay(400),\n          tap(el => {\n            el.innerHTML = \"\"\n            el.remove()\n          })\n        )\n      )\n    )\n      .subscribe(noop)\n\n  /* Return dialog */\n  return dialog$\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, OperatorFunction, of, pipe } from \"rxjs\"\nimport { map, switchMap } from \"rxjs/operators\"\n\nimport { Viewport } from \"browser\"\n\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\nimport {\n  Sidebar,\n  applySidebar,\n  watchSidebar\n} from \"../shared\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Navigation for [screen -]\n */\ninterface NavigationBelowScreen {} // tslint:disable-line\n\n/**\n * Navigation for [screen +]\n */\ninterface NavigationAboveScreen {\n  sidebar: Sidebar                     /* Sidebar */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Navigation\n */\nexport type Navigation =\n  | NavigationBelowScreen\n  | NavigationAboveScreen\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  header$: Observable<Header>          /* Header observable */\n  main$: Observable<Main>              /* Main area observable */\n  viewport$: Observable<Viewport>      /* Viewport observable */\n  screen$: Observable<boolean>         /* Screen media observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount navigation from source observable\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountNavigation(\n  { header$, main$, viewport$, screen$ }: MountOptions\n): OperatorFunction<HTMLElement, Navigation> {\n  return pipe(\n    switchMap(el => screen$\n      .pipe(\n        switchMap(screen => {\n\n          /* [screen +]: Mount navigation in sidebar */\n          if (screen) {\n            return watchSidebar(el, { main$, viewport$ })\n              .pipe(\n                applySidebar(el, { header$ }),\n                map(sidebar => ({ sidebar }))\n              )\n\n          /* [screen -]: Mount navigation in drawer */\n          } else {\n            return of({})\n          }\n        })\n      )\n    )\n  )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"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, OperatorFunction, combineLatest, pipe } from \"rxjs\"\nimport {\n  filter,\n  map,\n  mapTo,\n  sample,\n  startWith,\n  switchMap,\n  take\n} from \"rxjs/operators\"\n\nimport { WorkerHandler } from \"browser\"\nimport {\n  SearchMessage,\n  SearchResult,\n  isSearchQueryMessage,\n  isSearchReadyMessage\n} from \"integrations/search\"\n\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search status\n */\nexport type SearchStatus =\n  | \"waiting\"                          /* Search waiting for initialization */\n  | \"ready\"                            /* Search ready */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search\n */\nexport interface Search {\n  status: SearchStatus                 /* Search status */\n  query: SearchQuery                   /* Search query */\n  result: SearchResult[]               /* Search result list */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n  query$: Observable<SearchQuery>      /* Search query observable */\n  reset$: Observable<void>             /* Search reset observable */\n  result$: Observable<SearchResult[]>  /* Search result observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search from source observable\n *\n * @param handler - Worker handler\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountSearch(\n  { rx$, tx$ }: WorkerHandler<SearchMessage>,\n  { query$, reset$, result$ }: MountOptions\n): OperatorFunction<HTMLElement, Search> {\n  return pipe(\n    switchMap(() => {\n\n      /* Compute search status */\n      const status$ = rx$\n        .pipe(\n          filter(isSearchReadyMessage),\n          mapTo<SearchStatus>(\"ready\"),\n          startWith(\"waiting\")\n        ) as Observable<SearchStatus>\n\n      /* Re-emit the latest query when search is ready */\n      tx$\n        .pipe(\n          filter(isSearchQueryMessage),\n          sample(status$),\n          take(1)\n        )\n          .subscribe(tx$.next.bind(tx$))\n\n      /* Combine into single observable */\n      return combineLatest([status$, query$, result$, reset$])\n        .pipe(\n          map(([status, query, result]) => ({\n            status,\n            query,\n            result\n          }))\n        )\n    })\n  )\n}\n"],"sourceRoot":""}