static: add footer buttons for theme switching and shortcuts modal

For golang/go#47421

Change-Id: I3b8dc2a94169e636f0b21587eeb76315052f361f
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/354595
Trust: Jamal Carvalho <jamal@golang.org>
Run-TryBot: Jamal Carvalho <jamal@golang.org>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/static/frontend/frontend.js b/static/frontend/frontend.js
index 02f1cf4..da8ea1c 100644
--- a/static/frontend/frontend.js
+++ b/static/frontend/frontend.js
@@ -1,4 +1,4 @@
-var _=Object.defineProperty;var R=e=>_(e,"__esModule",{value:!0});var j=(e,t)=>()=>(e&&(t=e(e=0)),t);var K=(e,t)=>{R(e);for(var o in t)_(e,o,{get:t[o],enumerable:!0})};var A={};K(A,{default:()=>z});function F(e){for(;e&&e!==document.body;){var t=window.getComputedStyle(e),o=function(i,n){return!(t[i]===void 0||t[i]===n)};if(t.opacity<1||o("zIndex","auto")||o("transform","none")||o("mixBlendMode","normal")||o("filter","none")||o("perspective","none")||t.isolation==="isolate"||t.position==="fixed"||t.webkitOverflowScrolling==="touch")return!0;e=e.parentElement}return!1}function u(e){for(;e;){if(e.localName==="dialog")return e;e=e.parentElement}return null}function T(e){e&&e.blur&&e!==document.body&&e.blur()}function U(e,t){for(var o=0;o<e.length;++o)if(e[o]===t)return!0;return!1}function h(e){return!e||!e.hasAttribute("method")?!1:e.getAttribute("method").toLowerCase()==="dialog"}function S(e){if(this.dialog_=e,this.replacedStyleTop_=!1,this.openAsModal_=!1,e.hasAttribute("role")||e.setAttribute("role","dialog"),e.show=this.show.bind(this),e.showModal=this.showModal.bind(this),e.close=this.close.bind(this),"returnValue"in e||(e.returnValue=""),"MutationObserver"in window){var t=new MutationObserver(this.maybeHideModal.bind(this));t.observe(e,{attributes:!0,attributeFilter:["open"]})}else{var o=!1,i=function(){o?this.downgradeModal():this.maybeHideModal(),o=!1}.bind(this),n,r=function(s){if(s.target===e){var l="DOMNodeRemoved";o|=s.type.substr(0,l.length)===l,window.clearTimeout(n),n=window.setTimeout(i,0)}};["DOMAttrModified","DOMNodeRemoved","DOMNodeRemovedFromDocument"].forEach(function(s){e.addEventListener(s,r)})}Object.defineProperty(e,"open",{set:this.setOpen.bind(this),get:e.hasAttribute.bind(e,"open")}),this.backdrop_=document.createElement("div"),this.backdrop_.className="backdrop",this.backdrop_.addEventListener("click",this.backdropClick_.bind(this))}var c,a,y,d,x,k,D,C,z,H=j(()=>{c=window.CustomEvent;(!c||typeof c=="object")&&(c=function(t,o){o=o||{};var i=document.createEvent("CustomEvent");return i.initCustomEvent(t,!!o.bubbles,!!o.cancelable,o.detail||null),i},c.prototype=window.Event.prototype);S.prototype={get dialog(){return this.dialog_},maybeHideModal:function(){this.dialog_.hasAttribute("open")&&document.body.contains(this.dialog_)||this.downgradeModal()},downgradeModal:function(){!this.openAsModal_||(this.openAsModal_=!1,this.dialog_.style.zIndex="",this.replacedStyleTop_&&(this.dialog_.style.top="",this.replacedStyleTop_=!1),this.backdrop_.parentNode&&this.backdrop_.parentNode.removeChild(this.backdrop_),a.dm.removeDialog(this))},setOpen:function(e){e?this.dialog_.hasAttribute("open")||this.dialog_.setAttribute("open",""):(this.dialog_.removeAttribute("open"),this.maybeHideModal())},backdropClick_:function(e){if(this.dialog_.hasAttribute("tabindex"))this.dialog_.focus();else{var t=document.createElement("div");this.dialog_.insertBefore(t,this.dialog_.firstChild),t.tabIndex=-1,t.focus(),this.dialog_.removeChild(t)}var o=document.createEvent("MouseEvents");o.initMouseEvent(e.type,e.bubbles,e.cancelable,window,e.detail,e.screenX,e.screenY,e.clientX,e.clientY,e.ctrlKey,e.altKey,e.shiftKey,e.metaKey,e.button,e.relatedTarget),this.dialog_.dispatchEvent(o),e.stopPropagation()},focus_:function(){var e=this.dialog_.querySelector("[autofocus]:not([disabled])");if(!e&&this.dialog_.tabIndex>=0&&(e=this.dialog_),!e){var t=["button","input","keygen","select","textarea"],o=t.map(function(i){return i+":not([disabled])"});o.push('[tabindex]:not([disabled]):not([tabindex=""])'),e=this.dialog_.querySelector(o.join(", "))}T(document.activeElement),e&&e.focus()},updateZIndex:function(e,t){if(e<t)throw new Error("dialogZ should never be < backdropZ");this.dialog_.style.zIndex=e,this.backdrop_.style.zIndex=t},show:function(){this.dialog_.open||(this.setOpen(!0),this.focus_())},showModal:function(){if(this.dialog_.hasAttribute("open"))throw new Error("Failed to execute 'showModal' on dialog: The element is already open, and therefore cannot be opened modally.");if(!document.body.contains(this.dialog_))throw new Error("Failed to execute 'showModal' on dialog: The element is not in a Document.");if(!a.dm.pushDialog(this))throw new Error("Failed to execute 'showModal' on dialog: There are too many open modal dialogs.");F(this.dialog_.parentElement)&&console.warn("A dialog is being shown inside a stacking context. This may cause it to be unusable. For more information, see this link: https://github.com/GoogleChrome/dialog-polyfill/#stacking-context"),this.setOpen(!0),this.openAsModal_=!0,a.needsCentering(this.dialog_)?(a.reposition(this.dialog_),this.replacedStyleTop_=!0):this.replacedStyleTop_=!1,this.dialog_.parentNode.insertBefore(this.backdrop_,this.dialog_.nextSibling),this.focus_()},close:function(e){if(!this.dialog_.hasAttribute("open"))throw new Error("Failed to execute 'close' on dialog: The element does not have an 'open' attribute, and therefore cannot be closed.");this.setOpen(!1),e!==void 0&&(this.dialog_.returnValue=e);var t=new c("close",{bubbles:!1,cancelable:!1});this.dialog_.dispatchEvent(t)}};a={};a.reposition=function(e){var t=document.body.scrollTop||document.documentElement.scrollTop,o=t+(window.innerHeight-e.offsetHeight)/2;e.style.top=Math.max(t,o)+"px"};a.isInlinePositionSetByStylesheet=function(e){for(var t=0;t<document.styleSheets.length;++t){var o=document.styleSheets[t],i=null;try{i=o.cssRules}catch(P){}if(!!i)for(var n=0;n<i.length;++n){var r=i[n],s=null;try{s=document.querySelectorAll(r.selectorText)}catch(P){}if(!(!s||!U(s,e))){var l=r.style.getPropertyValue("top"),E=r.style.getPropertyValue("bottom");if(l&&l!=="auto"||E&&E!=="auto")return!0}}}return!1};a.needsCentering=function(e){var t=window.getComputedStyle(e);return t.position!=="absolute"||e.style.top!=="auto"&&e.style.top!==""||e.style.bottom!=="auto"&&e.style.bottom!==""?!1:!a.isInlinePositionSetByStylesheet(e)};a.forceRegisterDialog=function(e){if((window.HTMLDialogElement||e.showModal)&&console.warn("This browser already supports <dialog>, the polyfill may not work correctly",e),e.localName!=="dialog")throw new Error("Failed to register dialog: The element is not a dialog.");new S(e)};a.registerDialog=function(e){e.showModal||a.forceRegisterDialog(e)};a.DialogManager=function(){this.pendingDialogStack=[];var e=this.checkDOM_.bind(this);this.overlay=document.createElement("div"),this.overlay.className="_dialog_overlay",this.overlay.addEventListener("click",function(t){this.forwardTab_=void 0,t.stopPropagation(),e([])}.bind(this)),this.handleKey_=this.handleKey_.bind(this),this.handleFocus_=this.handleFocus_.bind(this),this.zIndexLow_=1e5,this.zIndexHigh_=1e5+150,this.forwardTab_=void 0,"MutationObserver"in window&&(this.mo_=new MutationObserver(function(t){var o=[];t.forEach(function(i){for(var n=0,r;r=i.removedNodes[n];++n){if(r instanceof Element)r.localName==="dialog"&&o.push(r);else continue;o=o.concat(r.querySelectorAll("dialog"))}}),o.length&&e(o)}))};a.DialogManager.prototype.blockDocument=function(){document.documentElement.addEventListener("focus",this.handleFocus_,!0),document.addEventListener("keydown",this.handleKey_),this.mo_&&this.mo_.observe(document,{childList:!0,subtree:!0})};a.DialogManager.prototype.unblockDocument=function(){document.documentElement.removeEventListener("focus",this.handleFocus_,!0),document.removeEventListener("keydown",this.handleKey_),this.mo_&&this.mo_.disconnect()};a.DialogManager.prototype.updateStacking=function(){for(var e=this.zIndexHigh_,t=0,o;o=this.pendingDialogStack[t];++t)o.updateZIndex(--e,--e),t===0&&(this.overlay.style.zIndex=--e);var i=this.pendingDialogStack[0];if(i){var n=i.dialog.parentNode||document.body;n.appendChild(this.overlay)}else this.overlay.parentNode&&this.overlay.parentNode.removeChild(this.overlay)};a.DialogManager.prototype.containedByTopDialog_=function(e){for(;e=u(e);){for(var t=0,o;o=this.pendingDialogStack[t];++t)if(o.dialog===e)return t===0;e=e.parentElement}return!1};a.DialogManager.prototype.handleFocus_=function(e){if(!this.containedByTopDialog_(e.target)&&document.activeElement!==document.documentElement&&(e.preventDefault(),e.stopPropagation(),T(e.target),this.forwardTab_!==void 0)){var t=this.pendingDialogStack[0],o=t.dialog,i=o.compareDocumentPosition(e.target);return i&Node.DOCUMENT_POSITION_PRECEDING&&(this.forwardTab_?t.focus_():e.target!==document.documentElement&&document.documentElement.focus()),!1}};a.DialogManager.prototype.handleKey_=function(e){if(this.forwardTab_=void 0,e.keyCode===27){e.preventDefault(),e.stopPropagation();var t=new c("cancel",{bubbles:!1,cancelable:!0}),o=this.pendingDialogStack[0];o&&o.dialog.dispatchEvent(t)&&o.dialog.close()}else e.keyCode===9&&(this.forwardTab_=!e.shiftKey)};a.DialogManager.prototype.checkDOM_=function(e){var t=this.pendingDialogStack.slice();t.forEach(function(o){e.indexOf(o.dialog)!==-1?o.downgradeModal():o.maybeHideModal()})};a.DialogManager.prototype.pushDialog=function(e){var t=(this.zIndexHigh_-this.zIndexLow_)/2-1;return this.pendingDialogStack.length>=t?!1:(this.pendingDialogStack.unshift(e)===1&&this.blockDocument(),this.updateStacking(),!0)};a.DialogManager.prototype.removeDialog=function(e){var t=this.pendingDialogStack.indexOf(e);t!==-1&&(this.pendingDialogStack.splice(t,1),this.pendingDialogStack.length===0&&this.unblockDocument(),this.updateStacking())};a.dm=new a.DialogManager;a.formSubmitter=null;a.useValue=null;window.HTMLDialogElement===void 0&&(y=document.createElement("form"),y.setAttribute("method","dialog"),y.method!=="dialog"&&(d=Object.getOwnPropertyDescriptor(HTMLFormElement.prototype,"method"),d&&(x=d.get,d.get=function(){return h(this)?"dialog":x.call(this)},k=d.set,d.set=function(e){return typeof e=="string"&&e.toLowerCase()==="dialog"?this.setAttribute("method",e):k.call(this,e)},Object.defineProperty(HTMLFormElement.prototype,"method",d))),document.addEventListener("click",function(e){if(a.formSubmitter=null,a.useValue=null,!e.defaultPrevented){var t=e.target;if(!(!t||!h(t.form))){var o=t.type==="submit"&&["button","input"].indexOf(t.localName)>-1;if(!o){if(!(t.localName==="input"&&t.type==="image"))return;a.useValue=e.offsetX+","+e.offsetY}var i=u(t);!i||(a.formSubmitter=t)}}},!1),D=HTMLFormElement.prototype.submit,C=function(){if(!h(this))return D.call(this);var e=u(this);e&&e.close()},HTMLFormElement.prototype.submit=C,document.addEventListener("submit",function(e){if(!e.defaultPrevented){var t=e.target;if(!!h(t)){e.preventDefault();var o=u(t);if(!!o){var i=a.formSubmitter;i&&i.form===t?o.close(a.useValue||i.value):o.close(),a.formSubmitter=null}}}},!1));z=a});function L(){let e=document.querySelector(".js-header"),t=document.querySelectorAll(".js-headerMenuButton");t.forEach(i=>{i.addEventListener("click",n=>{n.preventDefault(),e==null||e.classList.toggle("is-active"),i.setAttribute("aria-expanded",String(e==null?void 0:e.classList.contains("is-active")))})});let o=document.querySelector(".js-scrim");o==null||o.addEventListener("click",i=>{i.preventDefault(),e==null||e.classList.remove("is-active"),t.forEach(n=>{n.setAttribute("aria-expanded",String(e==null?void 0:e.classList.contains("is-active")))})})}function M(){let e=document.querySelector(".js-searchForm"),t=document.querySelector(".js-expandSearch"),o=e==null?void 0:e.querySelector("input"),i=document.querySelector(".js-headerLogo"),n=document.querySelector(".js-headerMenuButton");t==null||t.addEventListener("click",()=>{e==null||e.classList.add("go-SearchForm--expanded"),i==null||i.classList.add("go-Header-logo--hidden"),n==null||n.classList.add("go-Header-navOpen--hidden"),o==null||o.focus()}),document==null||document.addEventListener("click",r=>{(e==null?void 0:e.contains(r.target))||(e==null||e.classList.remove("go-SearchForm--expanded"),i==null||i.classList.remove("go-Header-logo--hidden"),n==null||n.classList.remove("go-Header-navOpen--hidden"))})}var g=class{constructor(t){this.el=t;this.setActive=t=>{this.activeIndex=(t+this.slides.length)%this.slides.length,this.el.setAttribute("data-slide-index",String(this.activeIndex));for(let o of this.dots)o.classList.remove("go-Carousel-dot--active");this.dots[this.activeIndex].classList.add("go-Carousel-dot--active");for(let o of this.slides)o.setAttribute("aria-hidden","true");this.slides[this.activeIndex].removeAttribute("aria-hidden"),this.liveRegion.textContent="Slide "+(this.activeIndex+1)+" of "+this.slides.length};var o;this.slides=Array.from(t.querySelectorAll(".go-Carousel-slide")),this.dots=[],this.liveRegion=document.createElement("div"),this.activeIndex=Number((o=t.getAttribute("data-slide-index"))!=null?o:0),this.initSlides(),this.initArrows(),this.initDots(),this.initLiveRegion()}initSlides(){for(let[t,o]of this.slides.entries())t!==this.activeIndex&&o.setAttribute("aria-hidden","true")}initArrows(){var o,i;let t=document.createElement("ul");t.classList.add("go-Carousel-arrows"),t.innerHTML=`
+var _=Object.defineProperty;var R=e=>_(e,"__esModule",{value:!0});var K=(e,t)=>()=>(e&&(t=e(e=0)),t);var F=(e,t)=>{R(e);for(var o in t)_(e,o,{get:t[o],enumerable:!0})};var A={};F(A,{default:()=>B});function U(e){for(;e&&e!==document.body;){var t=window.getComputedStyle(e),o=function(i,n){return!(t[i]===void 0||t[i]===n)};if(t.opacity<1||o("zIndex","auto")||o("transform","none")||o("mixBlendMode","normal")||o("filter","none")||o("perspective","none")||t.isolation==="isolate"||t.position==="fixed"||t.webkitOverflowScrolling==="touch")return!0;e=e.parentElement}return!1}function u(e){for(;e;){if(e.localName==="dialog")return e;e=e.parentElement}return null}function T(e){e&&e.blur&&e!==document.body&&e.blur()}function z(e,t){for(var o=0;o<e.length;++o)if(e[o]===t)return!0;return!1}function h(e){return!e||!e.hasAttribute("method")?!1:e.getAttribute("method").toLowerCase()==="dialog"}function S(e){if(this.dialog_=e,this.replacedStyleTop_=!1,this.openAsModal_=!1,e.hasAttribute("role")||e.setAttribute("role","dialog"),e.show=this.show.bind(this),e.showModal=this.showModal.bind(this),e.close=this.close.bind(this),"returnValue"in e||(e.returnValue=""),"MutationObserver"in window){var t=new MutationObserver(this.maybeHideModal.bind(this));t.observe(e,{attributes:!0,attributeFilter:["open"]})}else{var o=!1,i=function(){o?this.downgradeModal():this.maybeHideModal(),o=!1}.bind(this),n,r=function(s){if(s.target===e){var l="DOMNodeRemoved";o|=s.type.substr(0,l.length)===l,window.clearTimeout(n),n=window.setTimeout(i,0)}};["DOMAttrModified","DOMNodeRemoved","DOMNodeRemovedFromDocument"].forEach(function(s){e.addEventListener(s,r)})}Object.defineProperty(e,"open",{set:this.setOpen.bind(this),get:e.hasAttribute.bind(e,"open")}),this.backdrop_=document.createElement("div"),this.backdrop_.className="backdrop",this.backdrop_.addEventListener("click",this.backdropClick_.bind(this))}var c,a,y,d,x,k,D,C,B,H=K(()=>{c=window.CustomEvent;(!c||typeof c=="object")&&(c=function(t,o){o=o||{};var i=document.createEvent("CustomEvent");return i.initCustomEvent(t,!!o.bubbles,!!o.cancelable,o.detail||null),i},c.prototype=window.Event.prototype);S.prototype={get dialog(){return this.dialog_},maybeHideModal:function(){this.dialog_.hasAttribute("open")&&document.body.contains(this.dialog_)||this.downgradeModal()},downgradeModal:function(){!this.openAsModal_||(this.openAsModal_=!1,this.dialog_.style.zIndex="",this.replacedStyleTop_&&(this.dialog_.style.top="",this.replacedStyleTop_=!1),this.backdrop_.parentNode&&this.backdrop_.parentNode.removeChild(this.backdrop_),a.dm.removeDialog(this))},setOpen:function(e){e?this.dialog_.hasAttribute("open")||this.dialog_.setAttribute("open",""):(this.dialog_.removeAttribute("open"),this.maybeHideModal())},backdropClick_:function(e){if(this.dialog_.hasAttribute("tabindex"))this.dialog_.focus();else{var t=document.createElement("div");this.dialog_.insertBefore(t,this.dialog_.firstChild),t.tabIndex=-1,t.focus(),this.dialog_.removeChild(t)}var o=document.createEvent("MouseEvents");o.initMouseEvent(e.type,e.bubbles,e.cancelable,window,e.detail,e.screenX,e.screenY,e.clientX,e.clientY,e.ctrlKey,e.altKey,e.shiftKey,e.metaKey,e.button,e.relatedTarget),this.dialog_.dispatchEvent(o),e.stopPropagation()},focus_:function(){var e=this.dialog_.querySelector("[autofocus]:not([disabled])");if(!e&&this.dialog_.tabIndex>=0&&(e=this.dialog_),!e){var t=["button","input","keygen","select","textarea"],o=t.map(function(i){return i+":not([disabled])"});o.push('[tabindex]:not([disabled]):not([tabindex=""])'),e=this.dialog_.querySelector(o.join(", "))}T(document.activeElement),e&&e.focus()},updateZIndex:function(e,t){if(e<t)throw new Error("dialogZ should never be < backdropZ");this.dialog_.style.zIndex=e,this.backdrop_.style.zIndex=t},show:function(){this.dialog_.open||(this.setOpen(!0),this.focus_())},showModal:function(){if(this.dialog_.hasAttribute("open"))throw new Error("Failed to execute 'showModal' on dialog: The element is already open, and therefore cannot be opened modally.");if(!document.body.contains(this.dialog_))throw new Error("Failed to execute 'showModal' on dialog: The element is not in a Document.");if(!a.dm.pushDialog(this))throw new Error("Failed to execute 'showModal' on dialog: There are too many open modal dialogs.");U(this.dialog_.parentElement)&&console.warn("A dialog is being shown inside a stacking context. This may cause it to be unusable. For more information, see this link: https://github.com/GoogleChrome/dialog-polyfill/#stacking-context"),this.setOpen(!0),this.openAsModal_=!0,a.needsCentering(this.dialog_)?(a.reposition(this.dialog_),this.replacedStyleTop_=!0):this.replacedStyleTop_=!1,this.dialog_.parentNode.insertBefore(this.backdrop_,this.dialog_.nextSibling),this.focus_()},close:function(e){if(!this.dialog_.hasAttribute("open"))throw new Error("Failed to execute 'close' on dialog: The element does not have an 'open' attribute, and therefore cannot be closed.");this.setOpen(!1),e!==void 0&&(this.dialog_.returnValue=e);var t=new c("close",{bubbles:!1,cancelable:!1});this.dialog_.dispatchEvent(t)}};a={};a.reposition=function(e){var t=document.body.scrollTop||document.documentElement.scrollTop,o=t+(window.innerHeight-e.offsetHeight)/2;e.style.top=Math.max(t,o)+"px"};a.isInlinePositionSetByStylesheet=function(e){for(var t=0;t<document.styleSheets.length;++t){var o=document.styleSheets[t],i=null;try{i=o.cssRules}catch(j){}if(!!i)for(var n=0;n<i.length;++n){var r=i[n],s=null;try{s=document.querySelectorAll(r.selectorText)}catch(j){}if(!(!s||!z(s,e))){var l=r.style.getPropertyValue("top"),E=r.style.getPropertyValue("bottom");if(l&&l!=="auto"||E&&E!=="auto")return!0}}}return!1};a.needsCentering=function(e){var t=window.getComputedStyle(e);return t.position!=="absolute"||e.style.top!=="auto"&&e.style.top!==""||e.style.bottom!=="auto"&&e.style.bottom!==""?!1:!a.isInlinePositionSetByStylesheet(e)};a.forceRegisterDialog=function(e){if((window.HTMLDialogElement||e.showModal)&&console.warn("This browser already supports <dialog>, the polyfill may not work correctly",e),e.localName!=="dialog")throw new Error("Failed to register dialog: The element is not a dialog.");new S(e)};a.registerDialog=function(e){e.showModal||a.forceRegisterDialog(e)};a.DialogManager=function(){this.pendingDialogStack=[];var e=this.checkDOM_.bind(this);this.overlay=document.createElement("div"),this.overlay.className="_dialog_overlay",this.overlay.addEventListener("click",function(t){this.forwardTab_=void 0,t.stopPropagation(),e([])}.bind(this)),this.handleKey_=this.handleKey_.bind(this),this.handleFocus_=this.handleFocus_.bind(this),this.zIndexLow_=1e5,this.zIndexHigh_=1e5+150,this.forwardTab_=void 0,"MutationObserver"in window&&(this.mo_=new MutationObserver(function(t){var o=[];t.forEach(function(i){for(var n=0,r;r=i.removedNodes[n];++n){if(r instanceof Element)r.localName==="dialog"&&o.push(r);else continue;o=o.concat(r.querySelectorAll("dialog"))}}),o.length&&e(o)}))};a.DialogManager.prototype.blockDocument=function(){document.documentElement.addEventListener("focus",this.handleFocus_,!0),document.addEventListener("keydown",this.handleKey_),this.mo_&&this.mo_.observe(document,{childList:!0,subtree:!0})};a.DialogManager.prototype.unblockDocument=function(){document.documentElement.removeEventListener("focus",this.handleFocus_,!0),document.removeEventListener("keydown",this.handleKey_),this.mo_&&this.mo_.disconnect()};a.DialogManager.prototype.updateStacking=function(){for(var e=this.zIndexHigh_,t=0,o;o=this.pendingDialogStack[t];++t)o.updateZIndex(--e,--e),t===0&&(this.overlay.style.zIndex=--e);var i=this.pendingDialogStack[0];if(i){var n=i.dialog.parentNode||document.body;n.appendChild(this.overlay)}else this.overlay.parentNode&&this.overlay.parentNode.removeChild(this.overlay)};a.DialogManager.prototype.containedByTopDialog_=function(e){for(;e=u(e);){for(var t=0,o;o=this.pendingDialogStack[t];++t)if(o.dialog===e)return t===0;e=e.parentElement}return!1};a.DialogManager.prototype.handleFocus_=function(e){if(!this.containedByTopDialog_(e.target)&&document.activeElement!==document.documentElement&&(e.preventDefault(),e.stopPropagation(),T(e.target),this.forwardTab_!==void 0)){var t=this.pendingDialogStack[0],o=t.dialog,i=o.compareDocumentPosition(e.target);return i&Node.DOCUMENT_POSITION_PRECEDING&&(this.forwardTab_?t.focus_():e.target!==document.documentElement&&document.documentElement.focus()),!1}};a.DialogManager.prototype.handleKey_=function(e){if(this.forwardTab_=void 0,e.keyCode===27){e.preventDefault(),e.stopPropagation();var t=new c("cancel",{bubbles:!1,cancelable:!0}),o=this.pendingDialogStack[0];o&&o.dialog.dispatchEvent(t)&&o.dialog.close()}else e.keyCode===9&&(this.forwardTab_=!e.shiftKey)};a.DialogManager.prototype.checkDOM_=function(e){var t=this.pendingDialogStack.slice();t.forEach(function(o){e.indexOf(o.dialog)!==-1?o.downgradeModal():o.maybeHideModal()})};a.DialogManager.prototype.pushDialog=function(e){var t=(this.zIndexHigh_-this.zIndexLow_)/2-1;return this.pendingDialogStack.length>=t?!1:(this.pendingDialogStack.unshift(e)===1&&this.blockDocument(),this.updateStacking(),!0)};a.DialogManager.prototype.removeDialog=function(e){var t=this.pendingDialogStack.indexOf(e);t!==-1&&(this.pendingDialogStack.splice(t,1),this.pendingDialogStack.length===0&&this.unblockDocument(),this.updateStacking())};a.dm=new a.DialogManager;a.formSubmitter=null;a.useValue=null;window.HTMLDialogElement===void 0&&(y=document.createElement("form"),y.setAttribute("method","dialog"),y.method!=="dialog"&&(d=Object.getOwnPropertyDescriptor(HTMLFormElement.prototype,"method"),d&&(x=d.get,d.get=function(){return h(this)?"dialog":x.call(this)},k=d.set,d.set=function(e){return typeof e=="string"&&e.toLowerCase()==="dialog"?this.setAttribute("method",e):k.call(this,e)},Object.defineProperty(HTMLFormElement.prototype,"method",d))),document.addEventListener("click",function(e){if(a.formSubmitter=null,a.useValue=null,!e.defaultPrevented){var t=e.target;if(!(!t||!h(t.form))){var o=t.type==="submit"&&["button","input"].indexOf(t.localName)>-1;if(!o){if(!(t.localName==="input"&&t.type==="image"))return;a.useValue=e.offsetX+","+e.offsetY}var i=u(t);!i||(a.formSubmitter=t)}}},!1),D=HTMLFormElement.prototype.submit,C=function(){if(!h(this))return D.call(this);var e=u(this);e&&e.close()},HTMLFormElement.prototype.submit=C,document.addEventListener("submit",function(e){if(!e.defaultPrevented){var t=e.target;if(!!h(t)){e.preventDefault();var o=u(t);if(!!o){var i=a.formSubmitter;i&&i.form===t?o.close(a.useValue||i.value):o.close(),a.formSubmitter=null}}}},!1));B=a});function L(){let e=document.querySelector(".js-header"),t=document.querySelectorAll(".js-headerMenuButton");t.forEach(i=>{i.addEventListener("click",n=>{n.preventDefault(),e==null||e.classList.toggle("is-active"),i.setAttribute("aria-expanded",String(e==null?void 0:e.classList.contains("is-active")))})});let o=document.querySelector(".js-scrim");o==null||o.addEventListener("click",i=>{i.preventDefault(),e==null||e.classList.remove("is-active"),t.forEach(n=>{n.setAttribute("aria-expanded",String(e==null?void 0:e.classList.contains("is-active")))})})}function M(){let e=document.querySelector(".js-searchForm"),t=document.querySelector(".js-expandSearch"),o=e==null?void 0:e.querySelector("input"),i=document.querySelector(".js-headerLogo"),n=document.querySelector(".js-headerMenuButton");t==null||t.addEventListener("click",()=>{e==null||e.classList.add("go-SearchForm--expanded"),i==null||i.classList.add("go-Header-logo--hidden"),n==null||n.classList.add("go-Header-navOpen--hidden"),o==null||o.focus()}),document==null||document.addEventListener("click",r=>{(e==null?void 0:e.contains(r.target))||(e==null||e.classList.remove("go-SearchForm--expanded"),i==null||i.classList.remove("go-Header-logo--hidden"),n==null||n.classList.remove("go-Header-navOpen--hidden"))})}var p=class{constructor(t){this.el=t;this.setActive=t=>{this.activeIndex=(t+this.slides.length)%this.slides.length,this.el.setAttribute("data-slide-index",String(this.activeIndex));for(let o of this.dots)o.classList.remove("go-Carousel-dot--active");this.dots[this.activeIndex].classList.add("go-Carousel-dot--active");for(let o of this.slides)o.setAttribute("aria-hidden","true");this.slides[this.activeIndex].removeAttribute("aria-hidden"),this.liveRegion.textContent="Slide "+(this.activeIndex+1)+" of "+this.slides.length};var o;this.slides=Array.from(t.querySelectorAll(".go-Carousel-slide")),this.dots=[],this.liveRegion=document.createElement("div"),this.activeIndex=Number((o=t.getAttribute("data-slide-index"))!=null?o:0),this.initSlides(),this.initArrows(),this.initDots(),this.initLiveRegion()}initSlides(){for(let[t,o]of this.slides.entries())t!==this.activeIndex&&o.setAttribute("aria-hidden","true")}initArrows(){var o,i;let t=document.createElement("ul");t.classList.add("go-Carousel-arrows"),t.innerHTML=`
       <li>
         <button class="go-Carousel-prevSlide" aria-label="Go to previous slide">
           <img class="go-Icon" height="24" width="24" src="/static/shared/icon/arrow_left_gm_grey_24dp.svg" alt="">
@@ -9,7 +9,7 @@
           <img class="go-Icon" height="24" width="24" src="/static/shared/icon/arrow_right_gm_grey_24dp.svg" alt="">
         </button>
       </li>
-    `,(o=t.querySelector(".go-Carousel-prevSlide"))==null||o.addEventListener("click",()=>this.setActive(this.activeIndex-1)),(i=t.querySelector(".go-Carousel-nextSlide"))==null||i.addEventListener("click",()=>this.setActive(this.activeIndex+1)),this.el.append(t)}initDots(){let t=document.createElement("ul");t.classList.add("go-Carousel-dots");for(let o=0;o<this.slides.length;o++){let i=document.createElement("li"),n=document.createElement("button");n.classList.add("go-Carousel-dot"),o===this.activeIndex&&n.classList.add("go-Carousel-dot--active"),n.innerHTML=`<span class="go-Carousel-obscured">Slide ${o+1}</span>`,n.addEventListener("click",()=>this.setActive(o)),i.append(n),t.append(i),this.dots.push(n)}this.el.append(t)}initLiveRegion(){this.liveRegion.setAttribute("aria-live","polite"),this.liveRegion.setAttribute("aria-atomic","true"),this.liveRegion.setAttribute("class","go-Carousel-obscured"),this.liveRegion.textContent=`Slide ${this.activeIndex+1} of ${this.slides.length}`,this.el.appendChild(this.liveRegion)}};var m=class{constructor(t){this.el=t;var o,i,n,r,s;this.data=(o=t.dataset.toCopy)!=null?o:t.innerText,!this.data&&((i=t.parentElement)==null?void 0:i.classList.contains("go-InputGroup"))&&(this.data=(s=this.data||((r=(n=t.parentElement)==null?void 0:n.querySelector("input"))==null?void 0:r.value))!=null?s:""),t.addEventListener("click",l=>this.handleCopyClick(l))}handleCopyClick(t){t.preventDefault();let o=1e3;if(!navigator.clipboard){this.showTooltipText("Unable to copy",o);return}navigator.clipboard.writeText(this.data).then(()=>{this.showTooltipText("Copied!",o)}).catch(()=>{this.showTooltipText("Unable to copy",o)})}showTooltipText(t,o){this.el.setAttribute("data-tooltip",t),setTimeout(()=>this.el.setAttribute("data-tooltip",""),o)}};var v=class{constructor(t){this.el=t;document.addEventListener("click",o=>{this.el.contains(o.target)||this.el.removeAttribute("open")})}};var b=class{constructor(t){this.el=t;this.el.addEventListener("change",o=>{let i=o.target,n=i.value;i.value.startsWith("/")||(n="/"+n),window.location.href=n})}};var w=class{constructor(t){this.el=t;!window.HTMLDialogElement&&!t.showModal&&Promise.resolve().then(()=>(H(),A)).then(({default:n})=>{n.registerDialog(t)});let o=t.id,i=document.querySelector(`[aria-controls="${o}"]`);i&&i.addEventListener("click",()=>{var n;this.el.showModal?this.el.showModal():this.el.open=!0,(n=t.querySelector("input"))==null||n.focus()});for(let n of this.el.querySelectorAll("[data-modal-close]"))n.addEventListener("click",()=>{this.el.close?this.el.close():this.el.open=!1})}};function f(e,t,o,i){var n;(n=window.dataLayer)!=null||(window.dataLayer=[]),typeof e=="string"?window.dataLayer.push({event:e,event_category:t,event_action:o,event_label:i}):window.dataLayer.push(e)}function I(e){var t;(t=window.dataLayer)!=null||(window.dataLayer=[]),window.dataLayer.push(e)}var O=class{constructor(){this.handlers={},document.addEventListener("keydown",t=>this.handleKeyPress(t))}on(t,o,i,n){var r,s;return(s=(r=this.handlers)[t])!=null||(r[t]=new Set),this.handlers[t].add({description:o,callback:i,...n}),this}handleKeyPress(t){var o;for(let i of(o=this.handlers[t.key.toLowerCase()])!=null?o:new Set){if(i.target&&i.target!==t.target)return;let n=t.target;if(!i.target&&((n==null?void 0:n.tagName)==="INPUT"||(n==null?void 0:n.tagName)==="SELECT"||(n==null?void 0:n.tagName)==="TEXTAREA")||(n==null?void 0:n.isContentEditable)||i.withMeta&&!(t.ctrlKey||t.metaKey)||!i.withMeta&&(t.ctrlKey||t.metaKey))return;f("keypress","hotkeys",`${t.key} pressed`,i.description),i.callback(t)}}},p=new O;L();M();for(let e of document.querySelectorAll(".js-clipboard"))new m(e);for(let e of document.querySelectorAll(".js-modal"))new w(e);for(let e of document.querySelectorAll(".js-tooltip"))new v(e);for(let e of document.querySelectorAll(".js-selectNav"))new b(e);for(let e of document.querySelectorAll(".js-carousel"))new g(e);p.on("t","toggle theme",()=>{let e="dark",t=document.documentElement.getAttribute("data-theme");t==="dark"?e="light":t==="light"&&(e="auto"),document.documentElement.setAttribute("data-theme",e),document.cookie=`prefers-color-scheme=${e};path=/;max-age=31536000;`});p.on("/","focus search",e=>{let t=Array.from(document.querySelectorAll(".js-searchFocus")).pop();t&&!window.navigator.userAgent.includes("Firefox")&&(e.preventDefault(),t.focus())});p.on("y","set canonical url",()=>{var t;let e=(t=document.querySelector(".js-canonicalURLPath"))==null?void 0:t.dataset.canonicalUrlPath;e&&e!==""&&window.history.replaceState(null,"",e)});(function(){f({"gtm.start":new Date().getTime(),event:"gtm.js"})})();function N(){let e=new URLSearchParams(window.location.search),t=e.get("utm_source");if(t!=="gopls"&&t!=="godoc"&&t!=="pkggodev")return;let o=new URL(window.location.href);e.delete("utm_source"),o.search=e.toString(),window.history.replaceState(null,"",o.toString())}var q;((q=document.querySelector(".js-gtmID"))==null?void 0:q.dataset.gtmid)&&window.dataLayer?I(function(){N()}):N();
+    `,(o=t.querySelector(".go-Carousel-prevSlide"))==null||o.addEventListener("click",()=>this.setActive(this.activeIndex-1)),(i=t.querySelector(".go-Carousel-nextSlide"))==null||i.addEventListener("click",()=>this.setActive(this.activeIndex+1)),this.el.append(t)}initDots(){let t=document.createElement("ul");t.classList.add("go-Carousel-dots");for(let o=0;o<this.slides.length;o++){let i=document.createElement("li"),n=document.createElement("button");n.classList.add("go-Carousel-dot"),o===this.activeIndex&&n.classList.add("go-Carousel-dot--active"),n.innerHTML=`<span class="go-Carousel-obscured">Slide ${o+1}</span>`,n.addEventListener("click",()=>this.setActive(o)),i.append(n),t.append(i),this.dots.push(n)}this.el.append(t)}initLiveRegion(){this.liveRegion.setAttribute("aria-live","polite"),this.liveRegion.setAttribute("aria-atomic","true"),this.liveRegion.setAttribute("class","go-Carousel-obscured"),this.liveRegion.textContent=`Slide ${this.activeIndex+1} of ${this.slides.length}`,this.el.appendChild(this.liveRegion)}};var m=class{constructor(t){this.el=t;var o,i,n,r,s;this.data=(o=t.dataset.toCopy)!=null?o:t.innerText,!this.data&&((i=t.parentElement)==null?void 0:i.classList.contains("go-InputGroup"))&&(this.data=(s=this.data||((r=(n=t.parentElement)==null?void 0:n.querySelector("input"))==null?void 0:r.value))!=null?s:""),t.addEventListener("click",l=>this.handleCopyClick(l))}handleCopyClick(t){t.preventDefault();let o=1e3;if(!navigator.clipboard){this.showTooltipText("Unable to copy",o);return}navigator.clipboard.writeText(this.data).then(()=>{this.showTooltipText("Copied!",o)}).catch(()=>{this.showTooltipText("Unable to copy",o)})}showTooltipText(t,o){this.el.setAttribute("data-tooltip",t),setTimeout(()=>this.el.setAttribute("data-tooltip",""),o)}};var v=class{constructor(t){this.el=t;document.addEventListener("click",o=>{this.el.contains(o.target)||this.el.removeAttribute("open")})}};var b=class{constructor(t){this.el=t;this.el.addEventListener("change",o=>{let i=o.target,n=i.value;i.value.startsWith("/")||(n="/"+n),window.location.href=n})}};var w=class{constructor(t){this.el=t;!window.HTMLDialogElement&&!t.showModal&&Promise.resolve().then(()=>(H(),A)).then(({default:n})=>{n.registerDialog(t)});let o=t.id,i=document.querySelector(`[aria-controls="${o}"]`);i&&i.addEventListener("click",()=>{var n;this.el.showModal?this.el.showModal():this.el.open=!0,(n=t.querySelector("input"))==null||n.focus()});for(let n of this.el.querySelectorAll("[data-modal-close]"))n.addEventListener("click",()=>{this.el.close?this.el.close():this.el.open=!1})}};function f(e,t,o,i){var n;(n=window.dataLayer)!=null||(window.dataLayer=[]),typeof e=="string"?window.dataLayer.push({event:e,event_category:t,event_action:o,event_label:i}):window.dataLayer.push(e)}function I(e){var t;(t=window.dataLayer)!=null||(window.dataLayer=[]),window.dataLayer.push(e)}var O=class{constructor(){this.handlers={},document.addEventListener("keydown",t=>this.handleKeyPress(t))}on(t,o,i,n){var r,s;return(s=(r=this.handlers)[t])!=null||(r[t]=new Set),this.handlers[t].add({description:o,callback:i,...n}),this}handleKeyPress(t){var o;for(let i of(o=this.handlers[t.key.toLowerCase()])!=null?o:new Set){if(i.target&&i.target!==t.target)return;let n=t.target;if(!i.target&&((n==null?void 0:n.tagName)==="INPUT"||(n==null?void 0:n.tagName)==="SELECT"||(n==null?void 0:n.tagName)==="TEXTAREA")||(n==null?void 0:n.isContentEditable)||i.withMeta&&!(t.ctrlKey||t.metaKey)||!i.withMeta&&(t.ctrlKey||t.metaKey))return;f("keypress","hotkeys",`${t.key} pressed`,i.description),i.callback(t)}}},g=new O;L();M();for(let e of document.querySelectorAll(".js-clipboard"))new m(e);for(let e of document.querySelectorAll(".js-modal"))new w(e);for(let e of document.querySelectorAll(".js-tooltip"))new v(e);for(let e of document.querySelectorAll(".js-selectNav"))new b(e);for(let e of document.querySelectorAll(".js-carousel"))new p(e);g.on("t","toggle theme",()=>{q()});g.on("/","focus search",e=>{let t=Array.from(document.querySelectorAll(".js-searchFocus")).pop();t&&!window.navigator.userAgent.includes("Firefox")&&(e.preventDefault(),t.focus())});g.on("y","set canonical url",()=>{var t;let e=(t=document.querySelector(".js-canonicalURLPath"))==null?void 0:t.dataset.canonicalUrlPath;e&&e!==""&&window.history.replaceState(null,"",e)});(function(){f({"gtm.start":new Date().getTime(),event:"gtm.js"})})();function N(){let e=new URLSearchParams(window.location.search),t=e.get("utm_source");if(t!=="gopls"&&t!=="godoc"&&t!=="pkggodev")return;let o=new URL(window.location.href);e.delete("utm_source"),o.search=e.toString(),window.history.replaceState(null,"",o.toString())}var P;((P=document.querySelector(".js-gtmID"))==null?void 0:P.dataset.gtmid)&&window.dataLayer?I(function(){N()}):N();for(let e of document.querySelectorAll(".js-toggleTheme"))e.addEventListener("click",()=>{q()});function q(){let e="dark",t=document.documentElement.getAttribute("data-theme");t==="dark"?e="light":t==="light"&&(e="auto"),document.documentElement.setAttribute("data-theme",e),document.cookie=`prefers-color-scheme=${e};path=/;max-age=31536000;`}
 /*!
  * @license
  * Copyright 2019-2020 The Go Authors. All rights reserved.
diff --git a/static/frontend/frontend.js.map b/static/frontend/frontend.js.map
index 5e942b0..68e72b0 100644
--- a/static/frontend/frontend.js.map
+++ b/static/frontend/frontend.js.map
@@ -1,7 +1,7 @@
 {
   "version": 3,
   "sources": ["../../third_party/dialog-polyfill/dialog-polyfill.esm.js", "../shared/header/header.ts", "../shared/carousel/carousel.ts", "../shared/clipboard/clipboard.ts", "../shared/tooltip/tooltip.ts", "../shared/outline/select.ts", "../shared/modal/modal.ts", "../shared/analytics/analytics.ts", "../shared/keyboard/keyboard.ts", "frontend.ts"],
-  "sourcesContent": ["// nb. This is for IE10 and lower _only_.\nvar supportCustomEvent = window.CustomEvent;\nif (!supportCustomEvent || typeof supportCustomEvent === 'object') {\n  supportCustomEvent = function CustomEvent(event, x) {\n    x = x || {};\n    var ev = document.createEvent('CustomEvent');\n    ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null);\n    return ev;\n  };\n  supportCustomEvent.prototype = window.Event.prototype;\n}\n\n/**\n * @param {Element} el to check for stacking context\n * @return {boolean} whether this el or its parents creates a stacking context\n */\nfunction createsStackingContext(el) {\n  while (el && el !== document.body) {\n    var s = window.getComputedStyle(el);\n    var invalid = function(k, ok) {\n      return !(s[k] === undefined || s[k] === ok);\n    };\n\n    if (s.opacity < 1 ||\n        invalid('zIndex', 'auto') ||\n        invalid('transform', 'none') ||\n        invalid('mixBlendMode', 'normal') ||\n        invalid('filter', 'none') ||\n        invalid('perspective', 'none') ||\n        s['isolation'] === 'isolate' ||\n        s.position === 'fixed' ||\n        s.webkitOverflowScrolling === 'touch') {\n      return true;\n    }\n    el = el.parentElement;\n  }\n  return false;\n}\n\n/**\n * Finds the nearest <dialog> from the passed element.\n *\n * @param {Element} el to search from\n * @return {HTMLDialogElement} dialog found\n */\nfunction findNearestDialog(el) {\n  while (el) {\n    if (el.localName === 'dialog') {\n      return /** @type {HTMLDialogElement} */ (el);\n    }\n    el = el.parentElement;\n  }\n  return null;\n}\n\n/**\n * Blur the specified element, as long as it's not the HTML body element.\n * This works around an IE9/10 bug - blurring the body causes Windows to\n * blur the whole application.\n *\n * @param {Element} el to blur\n */\nfunction safeBlur(el) {\n  if (el && el.blur && el !== document.body) {\n    el.blur();\n  }\n}\n\n/**\n * @param {!NodeList} nodeList to search\n * @param {Node} node to find\n * @return {boolean} whether node is inside nodeList\n */\nfunction inNodeList(nodeList, node) {\n  for (var i = 0; i < nodeList.length; ++i) {\n    if (nodeList[i] === node) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * @param {HTMLFormElement} el to check\n * @return {boolean} whether this form has method=\"dialog\"\n */\nfunction isFormMethodDialog(el) {\n  if (!el || !el.hasAttribute('method')) {\n    return false;\n  }\n  return el.getAttribute('method').toLowerCase() === 'dialog';\n}\n\n/**\n * @param {!HTMLDialogElement} dialog to upgrade\n * @constructor\n */\nfunction dialogPolyfillInfo(dialog) {\n  this.dialog_ = dialog;\n  this.replacedStyleTop_ = false;\n  this.openAsModal_ = false;\n\n  // Set a11y role. Browsers that support dialog implicitly know this already.\n  if (!dialog.hasAttribute('role')) {\n    dialog.setAttribute('role', 'dialog');\n  }\n\n  dialog.show = this.show.bind(this);\n  dialog.showModal = this.showModal.bind(this);\n  dialog.close = this.close.bind(this);\n\n  if (!('returnValue' in dialog)) {\n    dialog.returnValue = '';\n  }\n\n  if ('MutationObserver' in window) {\n    var mo = new MutationObserver(this.maybeHideModal.bind(this));\n    mo.observe(dialog, {attributes: true, attributeFilter: ['open']});\n  } else {\n    // IE10 and below support. Note that DOMNodeRemoved etc fire _before_ removal. They also\n    // seem to fire even if the element was removed as part of a parent removal. Use the removed\n    // events to force downgrade (useful if removed/immediately added).\n    var removed = false;\n    var cb = function() {\n      removed ? this.downgradeModal() : this.maybeHideModal();\n      removed = false;\n    }.bind(this);\n    var timeout;\n    var delayModel = function(ev) {\n      if (ev.target !== dialog) { return; }  // not for a child element\n      var cand = 'DOMNodeRemoved';\n      removed |= (ev.type.substr(0, cand.length) === cand);\n      window.clearTimeout(timeout);\n      timeout = window.setTimeout(cb, 0);\n    };\n    ['DOMAttrModified', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument'].forEach(function(name) {\n      dialog.addEventListener(name, delayModel);\n    });\n  }\n  // Note that the DOM is observed inside DialogManager while any dialog\n  // is being displayed as a modal, to catch modal removal from the DOM.\n\n  Object.defineProperty(dialog, 'open', {\n    set: this.setOpen.bind(this),\n    get: dialog.hasAttribute.bind(dialog, 'open')\n  });\n\n  this.backdrop_ = document.createElement('div');\n  this.backdrop_.className = 'backdrop';\n  this.backdrop_.addEventListener('click', this.backdropClick_.bind(this));\n}\n\ndialogPolyfillInfo.prototype = {\n\n  get dialog() {\n    return this.dialog_;\n  },\n\n  /**\n   * Maybe remove this dialog from the modal top layer. This is called when\n   * a modal dialog may no longer be tenable, e.g., when the dialog is no\n   * longer open or is no longer part of the DOM.\n   */\n  maybeHideModal: function() {\n    if (this.dialog_.hasAttribute('open') && document.body.contains(this.dialog_)) { return; }\n    this.downgradeModal();\n  },\n\n  /**\n   * Remove this dialog from the modal top layer, leaving it as a non-modal.\n   */\n  downgradeModal: function() {\n    if (!this.openAsModal_) { return; }\n    this.openAsModal_ = false;\n    this.dialog_.style.zIndex = '';\n\n    // This won't match the native <dialog> exactly because if the user set top on a centered\n    // polyfill dialog, that top gets thrown away when the dialog is closed. Not sure it's\n    // possible to polyfill this perfectly.\n    if (this.replacedStyleTop_) {\n      this.dialog_.style.top = '';\n      this.replacedStyleTop_ = false;\n    }\n\n    // Clear the backdrop and remove from the manager.\n    this.backdrop_.parentNode && this.backdrop_.parentNode.removeChild(this.backdrop_);\n    dialogPolyfill.dm.removeDialog(this);\n  },\n\n  /**\n   * @param {boolean} value whether to open or close this dialog\n   */\n  setOpen: function(value) {\n    if (value) {\n      this.dialog_.hasAttribute('open') || this.dialog_.setAttribute('open', '');\n    } else {\n      this.dialog_.removeAttribute('open');\n      this.maybeHideModal();  // nb. redundant with MutationObserver\n    }\n  },\n\n  /**\n   * Handles clicks on the fake .backdrop element, redirecting them as if\n   * they were on the dialog itself.\n   *\n   * @param {!Event} e to redirect\n   */\n  backdropClick_: function(e) {\n    if (!this.dialog_.hasAttribute('tabindex')) {\n      // Clicking on the backdrop should move the implicit cursor, even if dialog cannot be\n      // focused. Create a fake thing to focus on. If the backdrop was _before_ the dialog, this\n      // would not be needed - clicks would move the implicit cursor there.\n      var fake = document.createElement('div');\n      this.dialog_.insertBefore(fake, this.dialog_.firstChild);\n      fake.tabIndex = -1;\n      fake.focus();\n      this.dialog_.removeChild(fake);\n    } else {\n      this.dialog_.focus();\n    }\n\n    var redirectedEvent = document.createEvent('MouseEvents');\n    redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window,\n        e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey,\n        e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);\n    this.dialog_.dispatchEvent(redirectedEvent);\n    e.stopPropagation();\n  },\n\n  /**\n   * Focuses on the first focusable element within the dialog. This will always blur the current\n   * focus, even if nothing within the dialog is found.\n   */\n  focus_: function() {\n    // Find element with `autofocus` attribute, or fall back to the first form/tabindex control.\n    var target = this.dialog_.querySelector('[autofocus]:not([disabled])');\n    if (!target && this.dialog_.tabIndex >= 0) {\n      target = this.dialog_;\n    }\n    if (!target) {\n      // Note that this is 'any focusable area'. This list is probably not exhaustive, but the\n      // alternative involves stepping through and trying to focus everything.\n      var opts = ['button', 'input', 'keygen', 'select', 'textarea'];\n      var query = opts.map(function(el) {\n        return el + ':not([disabled])';\n      });\n      // TODO(samthor): tabindex values that are not numeric are not focusable.\n      query.push('[tabindex]:not([disabled]):not([tabindex=\"\"])');  // tabindex != \"\", not disabled\n      target = this.dialog_.querySelector(query.join(', '));\n    }\n    safeBlur(document.activeElement);\n    target && target.focus();\n  },\n\n  /**\n   * Sets the zIndex for the backdrop and dialog.\n   *\n   * @param {number} dialogZ\n   * @param {number} backdropZ\n   */\n  updateZIndex: function(dialogZ, backdropZ) {\n    if (dialogZ < backdropZ) {\n      throw new Error('dialogZ should never be < backdropZ');\n    }\n    this.dialog_.style.zIndex = dialogZ;\n    this.backdrop_.style.zIndex = backdropZ;\n  },\n\n  /**\n   * Shows the dialog. If the dialog is already open, this does nothing.\n   */\n  show: function() {\n    if (!this.dialog_.open) {\n      this.setOpen(true);\n      this.focus_();\n    }\n  },\n\n  /**\n   * Show this dialog modally.\n   */\n  showModal: function() {\n    if (this.dialog_.hasAttribute('open')) {\n      throw new Error('Failed to execute \\'showModal\\' on dialog: The element is already open, and therefore cannot be opened modally.');\n    }\n    if (!document.body.contains(this.dialog_)) {\n      throw new Error('Failed to execute \\'showModal\\' on dialog: The element is not in a Document.');\n    }\n    if (!dialogPolyfill.dm.pushDialog(this)) {\n      throw new Error('Failed to execute \\'showModal\\' on dialog: There are too many open modal dialogs.');\n    }\n\n    if (createsStackingContext(this.dialog_.parentElement)) {\n      console.warn('A dialog is being shown inside a stacking context. ' +\n          'This may cause it to be unusable. For more information, see this link: ' +\n          'https://github.com/GoogleChrome/dialog-polyfill/#stacking-context');\n    }\n\n    this.setOpen(true);\n    this.openAsModal_ = true;\n\n    // Optionally center vertically, relative to the current viewport.\n    if (dialogPolyfill.needsCentering(this.dialog_)) {\n      dialogPolyfill.reposition(this.dialog_);\n      this.replacedStyleTop_ = true;\n    } else {\n      this.replacedStyleTop_ = false;\n    }\n\n    // Insert backdrop.\n    this.dialog_.parentNode.insertBefore(this.backdrop_, this.dialog_.nextSibling);\n\n    // Focus on whatever inside the dialog.\n    this.focus_();\n  },\n\n  /**\n   * Closes this HTMLDialogElement. This is optional vs clearing the open\n   * attribute, however this fires a 'close' event.\n   *\n   * @param {string=} opt_returnValue to use as the returnValue\n   */\n  close: function(opt_returnValue) {\n    if (!this.dialog_.hasAttribute('open')) {\n      throw new Error('Failed to execute \\'close\\' on dialog: The element does not have an \\'open\\' attribute, and therefore cannot be closed.');\n    }\n    this.setOpen(false);\n\n    // Leave returnValue untouched in case it was set directly on the element\n    if (opt_returnValue !== undefined) {\n      this.dialog_.returnValue = opt_returnValue;\n    }\n\n    // Triggering \"close\" event for any attached listeners on the <dialog>.\n    var closeEvent = new supportCustomEvent('close', {\n      bubbles: false,\n      cancelable: false\n    });\n    this.dialog_.dispatchEvent(closeEvent);\n  }\n\n};\n\nvar dialogPolyfill = {};\n\ndialogPolyfill.reposition = function(element) {\n  var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;\n  var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2;\n  element.style.top = Math.max(scrollTop, topValue) + 'px';\n};\n\ndialogPolyfill.isInlinePositionSetByStylesheet = function(element) {\n  for (var i = 0; i < document.styleSheets.length; ++i) {\n    var styleSheet = document.styleSheets[i];\n    var cssRules = null;\n    // Some browsers throw on cssRules.\n    try {\n      cssRules = styleSheet.cssRules;\n    } catch (e) {}\n    if (!cssRules) { continue; }\n    for (var j = 0; j < cssRules.length; ++j) {\n      var rule = cssRules[j];\n      var selectedNodes = null;\n      // Ignore errors on invalid selector texts.\n      try {\n        selectedNodes = document.querySelectorAll(rule.selectorText);\n      } catch(e) {}\n      if (!selectedNodes || !inNodeList(selectedNodes, element)) {\n        continue;\n      }\n      var cssTop = rule.style.getPropertyValue('top');\n      var cssBottom = rule.style.getPropertyValue('bottom');\n      if ((cssTop && cssTop !== 'auto') || (cssBottom && cssBottom !== 'auto')) {\n        return true;\n      }\n    }\n  }\n  return false;\n};\n\ndialogPolyfill.needsCentering = function(dialog) {\n  var computedStyle = window.getComputedStyle(dialog);\n  if (computedStyle.position !== 'absolute') {\n    return false;\n  }\n\n  // We must determine whether the top/bottom specified value is non-auto.  In\n  // WebKit/Blink, checking computedStyle.top == 'auto' is sufficient, but\n  // Firefox returns the used value. So we do this crazy thing instead: check\n  // the inline style and then go through CSS rules.\n  if ((dialog.style.top !== 'auto' && dialog.style.top !== '') ||\n      (dialog.style.bottom !== 'auto' && dialog.style.bottom !== '')) {\n    return false;\n  }\n  return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog);\n};\n\n/**\n * @param {!Element} element to force upgrade\n */\ndialogPolyfill.forceRegisterDialog = function(element) {\n  if (window.HTMLDialogElement || element.showModal) {\n    console.warn('This browser already supports <dialog>, the polyfill ' +\n        'may not work correctly', element);\n  }\n  if (element.localName !== 'dialog') {\n    throw new Error('Failed to register dialog: The element is not a dialog.');\n  }\n  new dialogPolyfillInfo(/** @type {!HTMLDialogElement} */ (element));\n};\n\n/**\n * @param {!Element} element to upgrade, if necessary\n */\ndialogPolyfill.registerDialog = function(element) {\n  if (!element.showModal) {\n    dialogPolyfill.forceRegisterDialog(element);\n  }\n};\n\n/**\n * @constructor\n */\ndialogPolyfill.DialogManager = function() {\n  /** @type {!Array<!dialogPolyfillInfo>} */\n  this.pendingDialogStack = [];\n\n  var checkDOM = this.checkDOM_.bind(this);\n\n  // The overlay is used to simulate how a modal dialog blocks the document.\n  // The blocking dialog is positioned on top of the overlay, and the rest of\n  // the dialogs on the pending dialog stack are positioned below it. In the\n  // actual implementation, the modal dialog stacking is controlled by the\n  // top layer, where z-index has no effect.\n  this.overlay = document.createElement('div');\n  this.overlay.className = '_dialog_overlay';\n  this.overlay.addEventListener('click', function(e) {\n    this.forwardTab_ = undefined;\n    e.stopPropagation();\n    checkDOM([]);  // sanity-check DOM\n  }.bind(this));\n\n  this.handleKey_ = this.handleKey_.bind(this);\n  this.handleFocus_ = this.handleFocus_.bind(this);\n\n  this.zIndexLow_ = 100000;\n  this.zIndexHigh_ = 100000 + 150;\n\n  this.forwardTab_ = undefined;\n\n  if ('MutationObserver' in window) {\n    this.mo_ = new MutationObserver(function(records) {\n      var removed = [];\n      records.forEach(function(rec) {\n        for (var i = 0, c; c = rec.removedNodes[i]; ++i) {\n          if (!(c instanceof Element)) {\n            continue;\n          } else if (c.localName === 'dialog') {\n            removed.push(c);\n          }\n          removed = removed.concat(c.querySelectorAll('dialog'));\n        }\n      });\n      removed.length && checkDOM(removed);\n    });\n  }\n};\n\n/**\n * Called on the first modal dialog being shown. Adds the overlay and related\n * handlers.\n */\ndialogPolyfill.DialogManager.prototype.blockDocument = function() {\n  document.documentElement.addEventListener('focus', this.handleFocus_, true);\n  document.addEventListener('keydown', this.handleKey_);\n  this.mo_ && this.mo_.observe(document, {childList: true, subtree: true});\n};\n\n/**\n * Called on the first modal dialog being removed, i.e., when no more modal\n * dialogs are visible.\n */\ndialogPolyfill.DialogManager.prototype.unblockDocument = function() {\n  document.documentElement.removeEventListener('focus', this.handleFocus_, true);\n  document.removeEventListener('keydown', this.handleKey_);\n  this.mo_ && this.mo_.disconnect();\n};\n\n/**\n * Updates the stacking of all known dialogs.\n */\ndialogPolyfill.DialogManager.prototype.updateStacking = function() {\n  var zIndex = this.zIndexHigh_;\n\n  for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {\n    dpi.updateZIndex(--zIndex, --zIndex);\n    if (i === 0) {\n      this.overlay.style.zIndex = --zIndex;\n    }\n  }\n\n  // Make the overlay a sibling of the dialog itself.\n  var last = this.pendingDialogStack[0];\n  if (last) {\n    var p = last.dialog.parentNode || document.body;\n    p.appendChild(this.overlay);\n  } else if (this.overlay.parentNode) {\n    this.overlay.parentNode.removeChild(this.overlay);\n  }\n};\n\n/**\n * @param {Element} candidate to check if contained or is the top-most modal dialog\n * @return {boolean} whether candidate is contained in top dialog\n */\ndialogPolyfill.DialogManager.prototype.containedByTopDialog_ = function(candidate) {\n  while (candidate = findNearestDialog(candidate)) {\n    for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {\n      if (dpi.dialog === candidate) {\n        return i === 0;  // only valid if top-most\n      }\n    }\n    candidate = candidate.parentElement;\n  }\n  return false;\n};\n\ndialogPolyfill.DialogManager.prototype.handleFocus_ = function(event) {\n  if (this.containedByTopDialog_(event.target)) { return; }\n\n  if (document.activeElement === document.documentElement) { return; }\n\n  event.preventDefault();\n  event.stopPropagation();\n  safeBlur(/** @type {Element} */ (event.target));\n\n  if (this.forwardTab_ === undefined) { return; }  // move focus only from a tab key\n\n  var dpi = this.pendingDialogStack[0];\n  var dialog = dpi.dialog;\n  var position = dialog.compareDocumentPosition(event.target);\n  if (position & Node.DOCUMENT_POSITION_PRECEDING) {\n    if (this.forwardTab_) {\n      // forward\n      dpi.focus_();\n    } else if (event.target !== document.documentElement) {\n      // backwards if we're not already focused on <html>\n      document.documentElement.focus();\n    }\n  }\n\n  return false;\n};\n\ndialogPolyfill.DialogManager.prototype.handleKey_ = function(event) {\n  this.forwardTab_ = undefined;\n  if (event.keyCode === 27) {\n    event.preventDefault();\n    event.stopPropagation();\n    var cancelEvent = new supportCustomEvent('cancel', {\n      bubbles: false,\n      cancelable: true\n    });\n    var dpi = this.pendingDialogStack[0];\n    if (dpi && dpi.dialog.dispatchEvent(cancelEvent)) {\n      dpi.dialog.close();\n    }\n  } else if (event.keyCode === 9) {\n    this.forwardTab_ = !event.shiftKey;\n  }\n};\n\n/**\n * Finds and downgrades any known modal dialogs that are no longer displayed. Dialogs that are\n * removed and immediately readded don't stay modal, they become normal.\n *\n * @param {!Array<!HTMLDialogElement>} removed that have definitely been removed\n */\ndialogPolyfill.DialogManager.prototype.checkDOM_ = function(removed) {\n  // This operates on a clone because it may cause it to change. Each change also calls\n  // updateStacking, which only actually needs to happen once. But who removes many modal dialogs\n  // at a time?!\n  var clone = this.pendingDialogStack.slice();\n  clone.forEach(function(dpi) {\n    if (removed.indexOf(dpi.dialog) !== -1) {\n      dpi.downgradeModal();\n    } else {\n      dpi.maybeHideModal();\n    }\n  });\n};\n\n/**\n * @param {!dialogPolyfillInfo} dpi\n * @return {boolean} whether the dialog was allowed\n */\ndialogPolyfill.DialogManager.prototype.pushDialog = function(dpi) {\n  var allowed = (this.zIndexHigh_ - this.zIndexLow_) / 2 - 1;\n  if (this.pendingDialogStack.length >= allowed) {\n    return false;\n  }\n  if (this.pendingDialogStack.unshift(dpi) === 1) {\n    this.blockDocument();\n  }\n  this.updateStacking();\n  return true;\n};\n\n/**\n * @param {!dialogPolyfillInfo} dpi\n */\ndialogPolyfill.DialogManager.prototype.removeDialog = function(dpi) {\n  var index = this.pendingDialogStack.indexOf(dpi);\n  if (index === -1) { return; }\n\n  this.pendingDialogStack.splice(index, 1);\n  if (this.pendingDialogStack.length === 0) {\n    this.unblockDocument();\n  }\n  this.updateStacking();\n};\n\ndialogPolyfill.dm = new dialogPolyfill.DialogManager();\ndialogPolyfill.formSubmitter = null;\ndialogPolyfill.useValue = null;\n\n/**\n * Installs global handlers, such as click listers and native method overrides. These are needed\n * even if a no dialog is registered, as they deal with <form method=\"dialog\">.\n */\nif (window.HTMLDialogElement === undefined) {\n\n  /**\n   * If HTMLFormElement translates method=\"DIALOG\" into 'get', then replace the descriptor with\n   * one that returns the correct value.\n   */\n  var testForm = document.createElement('form');\n  testForm.setAttribute('method', 'dialog');\n  if (testForm.method !== 'dialog') {\n    var methodDescriptor = Object.getOwnPropertyDescriptor(HTMLFormElement.prototype, 'method');\n    if (methodDescriptor) {\n      // nb. Some older iOS and older PhantomJS fail to return the descriptor. Don't do anything\n      // and don't bother to update the element.\n      var realGet = methodDescriptor.get;\n      methodDescriptor.get = function() {\n        if (isFormMethodDialog(this)) {\n          return 'dialog';\n        }\n        return realGet.call(this);\n      };\n      var realSet = methodDescriptor.set;\n      methodDescriptor.set = function(v) {\n        if (typeof v === 'string' && v.toLowerCase() === 'dialog') {\n          return this.setAttribute('method', v);\n        }\n        return realSet.call(this, v);\n      };\n      Object.defineProperty(HTMLFormElement.prototype, 'method', methodDescriptor);\n    }\n  }\n\n  /**\n   * Global 'click' handler, to capture the <input type=\"submit\"> or <button> element which has\n   * submitted a <form method=\"dialog\">. Needed as Safari and others don't report this inside\n   * document.activeElement.\n   */\n  document.addEventListener('click', function(ev) {\n    dialogPolyfill.formSubmitter = null;\n    dialogPolyfill.useValue = null;\n    if (ev.defaultPrevented) { return; }  // e.g. a submit which prevents default submission\n\n    var target = /** @type {Element} */ (ev.target);\n    if (!target || !isFormMethodDialog(target.form)) { return; }\n\n    var valid = (target.type === 'submit' && ['button', 'input'].indexOf(target.localName) > -1);\n    if (!valid) {\n      if (!(target.localName === 'input' && target.type === 'image')) { return; }\n      // this is a <input type=\"image\">, which can submit forms\n      dialogPolyfill.useValue = ev.offsetX + ',' + ev.offsetY;\n    }\n\n    var dialog = findNearestDialog(target);\n    if (!dialog) { return; }\n\n    dialogPolyfill.formSubmitter = target;\n\n  }, false);\n\n  /**\n   * Replace the native HTMLFormElement.submit() method, as it won't fire the\n   * submit event and give us a chance to respond.\n   */\n  var nativeFormSubmit = HTMLFormElement.prototype.submit;\n  var replacementFormSubmit = function () {\n    if (!isFormMethodDialog(this)) {\n      return nativeFormSubmit.call(this);\n    }\n    var dialog = findNearestDialog(this);\n    dialog && dialog.close();\n  };\n  HTMLFormElement.prototype.submit = replacementFormSubmit;\n\n  /**\n   * Global form 'dialog' method handler. Closes a dialog correctly on submit\n   * and possibly sets its return value.\n   */\n  document.addEventListener('submit', function(ev) {\n    if (ev.defaultPrevented) { return; }  // e.g. a submit which prevents default submission\n\n    var form = /** @type {HTMLFormElement} */ (ev.target);\n    if (!isFormMethodDialog(form)) { return; }\n    ev.preventDefault();\n\n    var dialog = findNearestDialog(form);\n    if (!dialog) { return; }\n\n    // Forms can only be submitted via .submit() or a click (?), but anyway: sanity-check that\n    // the submitter is correct before using its value as .returnValue.\n    var s = dialogPolyfill.formSubmitter;\n    if (s && s.form === form) {\n      dialog.close(dialogPolyfill.useValue || s.value);\n    } else {\n      dialog.close();\n    }\n    dialogPolyfill.formSubmitter = null;\n\n  }, false);\n}\n\nexport default dialogPolyfill;\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nexport function registerHeaderListeners(): void {\n  const header = document.querySelector('.js-header');\n  const menuButtons = document.querySelectorAll('.js-headerMenuButton');\n  menuButtons.forEach(button => {\n    button.addEventListener('click', e => {\n      e.preventDefault();\n      header?.classList.toggle('is-active');\n      button.setAttribute('aria-expanded', String(header?.classList.contains('is-active')));\n    });\n  });\n\n  const scrim = document.querySelector('.js-scrim');\n  scrim?.addEventListener('click', e => {\n    e.preventDefault();\n    header?.classList.remove('is-active');\n    menuButtons.forEach(button => {\n      button.setAttribute('aria-expanded', String(header?.classList.contains('is-active')));\n    });\n  });\n}\n\nexport function registerSearchFormListeners(): void {\n  const searchForm = document.querySelector('.js-searchForm');\n  const expandSearch = document.querySelector('.js-expandSearch');\n  const input = searchForm?.querySelector('input');\n  const headerLogo = document.querySelector('.js-headerLogo');\n  const menuButton = document.querySelector('.js-headerMenuButton');\n  expandSearch?.addEventListener('click', () => {\n    searchForm?.classList.add('go-SearchForm--expanded');\n    headerLogo?.classList.add('go-Header-logo--hidden');\n    menuButton?.classList.add('go-Header-navOpen--hidden');\n    input?.focus();\n  });\n  document?.addEventListener('click', e => {\n    if (!searchForm?.contains(e.target as Node)) {\n      searchForm?.classList.remove('go-SearchForm--expanded');\n      headerLogo?.classList.remove('go-Header-logo--hidden');\n      menuButton?.classList.remove('go-Header-navOpen--hidden');\n    }\n  });\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * Carousel Controller adds event listeners, accessibilty enhancements, and\n * control elements to a carousel component.\n */\nexport class CarouselController {\n  /**\n   * slides is a collection of slides in the carousel.\n   */\n  private slides: HTMLLIElement[];\n  /**\n   * dots is a collection of dot navigation controls, added to the carousel\n   * by this controller.\n   */\n  private dots: HTMLElement[];\n  /**\n   * liveRegion is a visually hidden element that notifies assitive devices\n   * of visual changes to the carousel. They are added to the carousel by\n   * this controller.\n   */\n  private liveRegion: HTMLElement;\n  /**\n   * activeIndex is the 0-index of the currently active slide.\n   */\n  private activeIndex: number;\n\n  constructor(private el: HTMLElement) {\n    this.slides = Array.from(el.querySelectorAll('.go-Carousel-slide'));\n    this.dots = [];\n    this.liveRegion = document.createElement('div');\n    this.activeIndex = Number(el.getAttribute('data-slide-index') ?? 0);\n\n    this.initSlides();\n    this.initArrows();\n    this.initDots();\n    this.initLiveRegion();\n  }\n\n  private initSlides() {\n    for (const [i, v] of this.slides.entries()) {\n      if (i === this.activeIndex) continue;\n      v.setAttribute('aria-hidden', 'true');\n    }\n  }\n\n  private initArrows() {\n    const arrows = document.createElement('ul');\n    arrows.classList.add('go-Carousel-arrows');\n    arrows.innerHTML = `\n      <li>\n        <button class=\"go-Carousel-prevSlide\" aria-label=\"Go to previous slide\">\n          <img class=\"go-Icon\" height=\"24\" width=\"24\" src=\"/static/shared/icon/arrow_left_gm_grey_24dp.svg\" alt=\"\">\n        </button>\n      </li>\n      <li>\n        <button class=\"go-Carousel-nextSlide\" aria-label=\"Go to next slide\">\n          <img class=\"go-Icon\" height=\"24\" width=\"24\" src=\"/static/shared/icon/arrow_right_gm_grey_24dp.svg\" alt=\"\">\n        </button>\n      </li>\n    `;\n    arrows\n      .querySelector('.go-Carousel-prevSlide')\n      ?.addEventListener('click', () => this.setActive(this.activeIndex - 1));\n    arrows\n      .querySelector('.go-Carousel-nextSlide')\n      ?.addEventListener('click', () => this.setActive(this.activeIndex + 1));\n    this.el.append(arrows);\n  }\n\n  private initDots() {\n    const dots = document.createElement('ul');\n    dots.classList.add('go-Carousel-dots');\n    for (let i = 0; i < this.slides.length; i++) {\n      const li = document.createElement('li');\n      const button = document.createElement('button');\n      button.classList.add('go-Carousel-dot');\n      if (i === this.activeIndex) {\n        button.classList.add('go-Carousel-dot--active');\n      }\n      button.innerHTML = `<span class=\"go-Carousel-obscured\">Slide ${i + 1}</span>`;\n      button.addEventListener('click', () => this.setActive(i));\n      li.append(button);\n      dots.append(li);\n      this.dots.push(button);\n    }\n    this.el.append(dots);\n  }\n\n  private initLiveRegion() {\n    this.liveRegion.setAttribute('aria-live', 'polite');\n    this.liveRegion.setAttribute('aria-atomic', 'true');\n    this.liveRegion.setAttribute('class', 'go-Carousel-obscured');\n    this.liveRegion.textContent = `Slide ${this.activeIndex + 1} of ${this.slides.length}`;\n    this.el.appendChild(this.liveRegion);\n  }\n\n  private setActive = (index: number) => {\n    this.activeIndex = (index + this.slides.length) % this.slides.length;\n    this.el.setAttribute('data-slide-index', String(this.activeIndex));\n    for (const d of this.dots) {\n      d.classList.remove('go-Carousel-dot--active');\n    }\n    this.dots[this.activeIndex].classList.add('go-Carousel-dot--active');\n    for (const s of this.slides) {\n      s.setAttribute('aria-hidden', 'true');\n    }\n    this.slides[this.activeIndex].removeAttribute('aria-hidden');\n    this.liveRegion.textContent = 'Slide ' + (this.activeIndex + 1) + ' of ' + this.slides.length;\n  };\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This class decorates an element to copy arbitrary data attached via a data-\n * attribute to the clipboard.\n */\nexport class ClipboardController {\n  /**\n   * The data to be copied to the clipboard.\n   */\n  private data: string;\n\n  /**\n   * @param el The element that will trigger copying text to the clipboard. The text is\n   * expected to be within its data-to-copy attribute.\n   */\n  constructor(private el: HTMLButtonElement) {\n    this.data = el.dataset['toCopy'] ?? el.innerText;\n    // if data-to-copy is empty and the button is part of an input group\n    // capture the value of the input.\n    if (!this.data && el.parentElement?.classList.contains('go-InputGroup')) {\n      this.data = (this.data || el.parentElement?.querySelector('input')?.value) ?? '';\n    }\n    el.addEventListener('click', e => this.handleCopyClick(e));\n  }\n\n  /**\n   * Handles when the primary element is clicked.\n   */\n  handleCopyClick(e: MouseEvent): void {\n    e.preventDefault();\n    const TOOLTIP_SHOW_DURATION_MS = 1000;\n\n    // This API is not available on iOS.\n    if (!navigator.clipboard) {\n      this.showTooltipText('Unable to copy', TOOLTIP_SHOW_DURATION_MS);\n      return;\n    }\n    navigator.clipboard\n      .writeText(this.data)\n      .then(() => {\n        this.showTooltipText('Copied!', TOOLTIP_SHOW_DURATION_MS);\n      })\n      .catch(() => {\n        this.showTooltipText('Unable to copy', TOOLTIP_SHOW_DURATION_MS);\n      });\n  }\n\n  /**\n   * Shows the given text in a tooltip for a specified amount of time, in milliseconds.\n   */\n  showTooltipText(text: string, durationMs: number): void {\n    this.el.setAttribute('data-tooltip', text);\n    setTimeout(() => this.el.setAttribute('data-tooltip', ''), durationMs);\n  }\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * ToolTipController handles closing tooltips on external clicks.\n */\nexport class ToolTipController {\n  constructor(private el: HTMLDetailsElement) {\n    document.addEventListener('click', e => {\n      const insideTooltip = this.el.contains(e.target as Element);\n      if (!insideTooltip) {\n        this.el.removeAttribute('open');\n      }\n    });\n  }\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { TreeNavController } from './tree.js';\n\nexport class SelectNavController {\n  constructor(private el: Element) {\n    this.el.addEventListener('change', e => {\n      const target = e.target as HTMLSelectElement;\n      let href = target.value;\n      if (!target.value.startsWith('/')) {\n        href = '/' + href;\n      }\n      window.location.href = href;\n    });\n  }\n}\n\nexport function makeSelectNav(tree: TreeNavController): HTMLLabelElement {\n  const label = document.createElement('label');\n  label.classList.add('go-Label');\n  label.setAttribute('aria-label', 'Menu');\n  const select = document.createElement('select');\n  select.classList.add('go-Select', 'js-selectNav');\n  label.appendChild(select);\n  const outline = document.createElement('optgroup');\n  outline.label = 'Outline';\n  select.appendChild(outline);\n  const groupMap: Record<string, HTMLOptGroupElement> = {};\n  let group: HTMLOptGroupElement;\n  for (const t of tree.treeitems) {\n    if (Number(t.depth) > 4) continue;\n    if (t.groupTreeitem) {\n      group = groupMap[t.groupTreeitem.label];\n      if (!group) {\n        group = groupMap[t.groupTreeitem.label] = document.createElement('optgroup');\n        group.label = t.groupTreeitem.label;\n        select.appendChild(group);\n      }\n    } else {\n      group = outline;\n    }\n    const o = document.createElement('option');\n    o.label = t.label;\n    o.textContent = t.label;\n    o.value = (t.el as HTMLAnchorElement).href.replace(window.location.origin, '').replace('/', '');\n    group.appendChild(o);\n  }\n  tree.addObserver(t => {\n    const hash = (t.el as HTMLAnchorElement).hash;\n    const value = select.querySelector<HTMLOptionElement>(`[value$=\"${hash}\"]`)?.value;\n    if (value) {\n      select.value = value;\n    }\n  }, 50);\n  return label;\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * ModalController registers a dialog element with the polyfill if\n * necessary for the current browser, add adds event listeners to\n * close and open modals.\n */\nexport class ModalController {\n  constructor(private el: HTMLDialogElement) {\n    // Only load the dialog polyfill if necessary for the environment.\n    if (!window.HTMLDialogElement && !el.showModal) {\n      import('../../../third_party/dialog-polyfill/dialog-polyfill.esm.js').then(\n        ({ default: polyfill }) => {\n          polyfill.registerDialog(el);\n        }\n      );\n    }\n    const id = el.id;\n    const button = document.querySelector<HTMLButtonElement>(`[aria-controls=\"${id}\"]`);\n    if (button) {\n      button.addEventListener('click', () => {\n        if (this.el.showModal) {\n          this.el.showModal();\n        } else {\n          this.el.open = true;\n        }\n        el.querySelector('input')?.focus();\n      });\n    }\n    for (const close of this.el.querySelectorAll<HTMLButtonElement>('[data-modal-close]')) {\n      close.addEventListener('click', () => {\n        if (this.el.close) {\n          this.el.close();\n        } else {\n          this.el.open = false;\n        }\n      });\n    }\n  }\n}\n", "interface TagManagerEvent {\n  /**\n   * event is the name of the event, used to filter events in\n   * Google Analytics.\n   */\n  event: string;\n\n  /**\n   * event_category is a name that you supply as a way to group objects\n   * that to analyze. Typically, you will use the same category name\n   * multiple times over related UI elements (buttons, links, etc).\n   */\n  event_category?: string;\n\n  /**\n   * event_action is used to name the type of event or interaction you\n   * want to measure for a particular web object. For example, with a\n   * single \"form\" category, you can analyze a number of specific events\n   * with this parameter, such as: form entered, form submitted.\n   */\n  event_action?: string;\n\n  /**\n   * event_label provide additional information for events that you want\n   * to analyze, such as the text label of a link.\n   */\n  event_label?: string;\n\n  /**\n   * gtm.start is used to initialize Google Tag Manager.\n   */\n  'gtm.start'?: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ndeclare global {\n  interface Window {\n    dataLayer?: (TagManagerEvent | VoidFunction)[];\n    ga?: unknown;\n  }\n}\n\n/**\n * track sends events to Google Tag Manager.\n */\nexport function track(\n  event: string | TagManagerEvent,\n  category?: string,\n  action?: string,\n  label?: string\n): void {\n  window.dataLayer ??= [];\n  if (typeof event === 'string') {\n    window.dataLayer.push({\n      event,\n      event_category: category,\n      event_action: action,\n      event_label: label,\n    });\n  } else {\n    window.dataLayer.push(event);\n  }\n}\n\n/**\n * func adds functions to run sequentionally after\n * Google Tag Manager is ready.\n */\nexport function func(fn: () => void): void {\n  window.dataLayer ??= [];\n  window.dataLayer.push(fn);\n}\n", "/*!\n * @license\n * Copyright 2019-2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { track } from '../analytics/analytics';\n\n/**\n * Options are keyhandler callback options.\n */\ninterface Options {\n  /**\n   * target is the element the key event should filter on. The\n   * default target is the document.\n   */\n  target?: Element;\n\n  /**\n   * withMeta specifies if the event callback should fire when\n   * the key is pressed with a meta key (ctrl, alt, etc). By\n   * default meta keypresses are ignored.\n   */\n  withMeta?: boolean;\n}\n\n/**\n * KeyHandler is the config for a keyboard event callback.\n */\ninterface KeyHandler extends Options {\n  description: string;\n  callback: (e: KeyboardEvent) => void;\n}\n\n/**\n * KeyboardController controls event callbacks for sitewide\n * keyboard events. Multiple callbacks can be registered for\n * a single key and by default the controller ignores events\n * for text input targets.\n */\nclass KeyboardController {\n  handlers: Record<string, Set<KeyHandler>>;\n\n  constructor() {\n    this.handlers = {};\n    document.addEventListener('keydown', e => this.handleKeyPress(e));\n  }\n\n  /**\n   * on registers keyboard event callbacks.\n   * @param key the key to register.\n   * @param description name of the event.\n   * @param callback event callback.\n   * @param options set target and withMeta options to override the default behaviors.\n   */\n  on(key: string, description: string, callback: (e: KeyboardEvent) => void, options?: Options) {\n    this.handlers[key] ??= new Set();\n    this.handlers[key].add({ description, callback, ...options });\n    return this;\n  }\n\n  private handleKeyPress(e: KeyboardEvent) {\n    for (const handler of this.handlers[e.key.toLowerCase()] ?? new Set()) {\n      if (handler.target && handler.target !== e.target) {\n        return;\n      }\n      const t = e.target as HTMLElement | null;\n      if (\n        !handler.target &&\n        (t?.tagName === 'INPUT' || t?.tagName === 'SELECT' || t?.tagName === 'TEXTAREA')\n      ) {\n        return;\n      }\n      if (t?.isContentEditable) {\n        return;\n      }\n      if (\n        (handler.withMeta && !(e.ctrlKey || e.metaKey)) ||\n        (!handler.withMeta && (e.ctrlKey || e.metaKey))\n      ) {\n        return;\n      }\n      track('keypress', 'hotkeys', `${e.key} pressed`, handler.description);\n      handler.callback(e);\n    }\n  }\n}\n\nexport const keyboard = new KeyboardController();\n", "/**\n * @license\n * Copyright 2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { registerHeaderListeners, registerSearchFormListeners } from 'static/shared/header/header';\nimport { CarouselController } from 'static/shared/carousel/carousel';\nimport { ClipboardController } from 'static/shared/clipboard/clipboard';\nimport { ToolTipController } from 'static/shared/tooltip/tooltip';\nimport { SelectNavController } from 'static/shared/outline/select';\nimport { ModalController } from 'static/shared/modal/modal';\n\nimport { keyboard } from 'static/shared/keyboard/keyboard';\nimport * as analytics from 'static/shared/analytics/analytics';\n\nregisterHeaderListeners();\nregisterSearchFormListeners();\n\nfor (const el of document.querySelectorAll<HTMLButtonElement>('.js-clipboard')) {\n  new ClipboardController(el);\n}\n\nfor (const el of document.querySelectorAll<HTMLDialogElement>('.js-modal')) {\n  new ModalController(el);\n}\n\nfor (const t of document.querySelectorAll<HTMLDetailsElement>('.js-tooltip')) {\n  new ToolTipController(t);\n}\n\nfor (const el of document.querySelectorAll<HTMLSelectElement>('.js-selectNav')) {\n  new SelectNavController(el);\n}\n\nfor (const el of document.querySelectorAll<HTMLSelectElement>('.js-carousel')) {\n  new CarouselController(el);\n}\n\n// Temporary shortcut for testing out the dark theme.\nkeyboard.on('t', 'toggle theme', () => {\n  let nextTheme = 'dark';\n  const theme = document.documentElement.getAttribute('data-theme');\n  if (theme === 'dark') {\n    nextTheme = 'light';\n  } else if (theme === 'light') {\n    nextTheme = 'auto';\n  }\n  document.documentElement.setAttribute('data-theme', nextTheme);\n  document.cookie = `prefers-color-scheme=${nextTheme};path=/;max-age=31536000;`;\n});\n\n// Pressing '/' focuses the search box\nkeyboard.on('/', 'focus search', e => {\n  const searchInput = Array.from(\n    document.querySelectorAll<HTMLInputElement>('.js-searchFocus')\n  ).pop();\n  // Favoring the Firefox quick find feature over search input\n  // focus. See: https://github.com/golang/go/issues/41093.\n  if (searchInput && !window.navigator.userAgent.includes('Firefox')) {\n    e.preventDefault();\n    searchInput.focus();\n  }\n});\n\n// Pressing 'y' changes the browser URL to the canonical URL\n// without triggering a reload.\nkeyboard.on('y', 'set canonical url', () => {\n  const canonicalURLPath = document.querySelector<HTMLDivElement>('.js-canonicalURLPath')?.dataset[\n    'canonicalUrlPath'\n  ];\n  if (canonicalURLPath && canonicalURLPath !== '') {\n    window.history.replaceState(null, '', canonicalURLPath);\n  }\n});\n\n/**\n * setupGoogleTagManager intializes Google Tag Manager.\n */\n(function setupGoogleTagManager() {\n  analytics.track({\n    'gtm.start': new Date().getTime(),\n    event: 'gtm.js',\n  });\n})();\n\n/**\n * removeUTMSource removes the utm_source GET parameter if present.\n * This is done using JavaScript, so that the utm_source is still\n * captured by Google Analytics.\n */\nfunction removeUTMSource() {\n  const urlParams = new URLSearchParams(window.location.search);\n  const utmSource = urlParams.get('utm_source');\n  if (utmSource !== 'gopls' && utmSource !== 'godoc' && utmSource !== 'pkggodev') {\n    return;\n  }\n\n  /** Strip the utm_source query parameter and replace the URL. **/\n  const newURL = new URL(window.location.href);\n  urlParams.delete('utm_source');\n  newURL.search = urlParams.toString();\n  window.history.replaceState(null, '', newURL.toString());\n}\n\nif (document.querySelector<HTMLElement>('.js-gtmID')?.dataset.gtmid && window.dataLayer) {\n  analytics.func(function () {\n    removeUTMSource();\n  });\n} else {\n  removeUTMSource();\n}\n"],
-  "mappings": "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",
+  "sourcesContent": ["// nb. This is for IE10 and lower _only_.\nvar supportCustomEvent = window.CustomEvent;\nif (!supportCustomEvent || typeof supportCustomEvent === 'object') {\n  supportCustomEvent = function CustomEvent(event, x) {\n    x = x || {};\n    var ev = document.createEvent('CustomEvent');\n    ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null);\n    return ev;\n  };\n  supportCustomEvent.prototype = window.Event.prototype;\n}\n\n/**\n * @param {Element} el to check for stacking context\n * @return {boolean} whether this el or its parents creates a stacking context\n */\nfunction createsStackingContext(el) {\n  while (el && el !== document.body) {\n    var s = window.getComputedStyle(el);\n    var invalid = function(k, ok) {\n      return !(s[k] === undefined || s[k] === ok);\n    };\n\n    if (s.opacity < 1 ||\n        invalid('zIndex', 'auto') ||\n        invalid('transform', 'none') ||\n        invalid('mixBlendMode', 'normal') ||\n        invalid('filter', 'none') ||\n        invalid('perspective', 'none') ||\n        s['isolation'] === 'isolate' ||\n        s.position === 'fixed' ||\n        s.webkitOverflowScrolling === 'touch') {\n      return true;\n    }\n    el = el.parentElement;\n  }\n  return false;\n}\n\n/**\n * Finds the nearest <dialog> from the passed element.\n *\n * @param {Element} el to search from\n * @return {HTMLDialogElement} dialog found\n */\nfunction findNearestDialog(el) {\n  while (el) {\n    if (el.localName === 'dialog') {\n      return /** @type {HTMLDialogElement} */ (el);\n    }\n    el = el.parentElement;\n  }\n  return null;\n}\n\n/**\n * Blur the specified element, as long as it's not the HTML body element.\n * This works around an IE9/10 bug - blurring the body causes Windows to\n * blur the whole application.\n *\n * @param {Element} el to blur\n */\nfunction safeBlur(el) {\n  if (el && el.blur && el !== document.body) {\n    el.blur();\n  }\n}\n\n/**\n * @param {!NodeList} nodeList to search\n * @param {Node} node to find\n * @return {boolean} whether node is inside nodeList\n */\nfunction inNodeList(nodeList, node) {\n  for (var i = 0; i < nodeList.length; ++i) {\n    if (nodeList[i] === node) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * @param {HTMLFormElement} el to check\n * @return {boolean} whether this form has method=\"dialog\"\n */\nfunction isFormMethodDialog(el) {\n  if (!el || !el.hasAttribute('method')) {\n    return false;\n  }\n  return el.getAttribute('method').toLowerCase() === 'dialog';\n}\n\n/**\n * @param {!HTMLDialogElement} dialog to upgrade\n * @constructor\n */\nfunction dialogPolyfillInfo(dialog) {\n  this.dialog_ = dialog;\n  this.replacedStyleTop_ = false;\n  this.openAsModal_ = false;\n\n  // Set a11y role. Browsers that support dialog implicitly know this already.\n  if (!dialog.hasAttribute('role')) {\n    dialog.setAttribute('role', 'dialog');\n  }\n\n  dialog.show = this.show.bind(this);\n  dialog.showModal = this.showModal.bind(this);\n  dialog.close = this.close.bind(this);\n\n  if (!('returnValue' in dialog)) {\n    dialog.returnValue = '';\n  }\n\n  if ('MutationObserver' in window) {\n    var mo = new MutationObserver(this.maybeHideModal.bind(this));\n    mo.observe(dialog, {attributes: true, attributeFilter: ['open']});\n  } else {\n    // IE10 and below support. Note that DOMNodeRemoved etc fire _before_ removal. They also\n    // seem to fire even if the element was removed as part of a parent removal. Use the removed\n    // events to force downgrade (useful if removed/immediately added).\n    var removed = false;\n    var cb = function() {\n      removed ? this.downgradeModal() : this.maybeHideModal();\n      removed = false;\n    }.bind(this);\n    var timeout;\n    var delayModel = function(ev) {\n      if (ev.target !== dialog) { return; }  // not for a child element\n      var cand = 'DOMNodeRemoved';\n      removed |= (ev.type.substr(0, cand.length) === cand);\n      window.clearTimeout(timeout);\n      timeout = window.setTimeout(cb, 0);\n    };\n    ['DOMAttrModified', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument'].forEach(function(name) {\n      dialog.addEventListener(name, delayModel);\n    });\n  }\n  // Note that the DOM is observed inside DialogManager while any dialog\n  // is being displayed as a modal, to catch modal removal from the DOM.\n\n  Object.defineProperty(dialog, 'open', {\n    set: this.setOpen.bind(this),\n    get: dialog.hasAttribute.bind(dialog, 'open')\n  });\n\n  this.backdrop_ = document.createElement('div');\n  this.backdrop_.className = 'backdrop';\n  this.backdrop_.addEventListener('click', this.backdropClick_.bind(this));\n}\n\ndialogPolyfillInfo.prototype = {\n\n  get dialog() {\n    return this.dialog_;\n  },\n\n  /**\n   * Maybe remove this dialog from the modal top layer. This is called when\n   * a modal dialog may no longer be tenable, e.g., when the dialog is no\n   * longer open or is no longer part of the DOM.\n   */\n  maybeHideModal: function() {\n    if (this.dialog_.hasAttribute('open') && document.body.contains(this.dialog_)) { return; }\n    this.downgradeModal();\n  },\n\n  /**\n   * Remove this dialog from the modal top layer, leaving it as a non-modal.\n   */\n  downgradeModal: function() {\n    if (!this.openAsModal_) { return; }\n    this.openAsModal_ = false;\n    this.dialog_.style.zIndex = '';\n\n    // This won't match the native <dialog> exactly because if the user set top on a centered\n    // polyfill dialog, that top gets thrown away when the dialog is closed. Not sure it's\n    // possible to polyfill this perfectly.\n    if (this.replacedStyleTop_) {\n      this.dialog_.style.top = '';\n      this.replacedStyleTop_ = false;\n    }\n\n    // Clear the backdrop and remove from the manager.\n    this.backdrop_.parentNode && this.backdrop_.parentNode.removeChild(this.backdrop_);\n    dialogPolyfill.dm.removeDialog(this);\n  },\n\n  /**\n   * @param {boolean} value whether to open or close this dialog\n   */\n  setOpen: function(value) {\n    if (value) {\n      this.dialog_.hasAttribute('open') || this.dialog_.setAttribute('open', '');\n    } else {\n      this.dialog_.removeAttribute('open');\n      this.maybeHideModal();  // nb. redundant with MutationObserver\n    }\n  },\n\n  /**\n   * Handles clicks on the fake .backdrop element, redirecting them as if\n   * they were on the dialog itself.\n   *\n   * @param {!Event} e to redirect\n   */\n  backdropClick_: function(e) {\n    if (!this.dialog_.hasAttribute('tabindex')) {\n      // Clicking on the backdrop should move the implicit cursor, even if dialog cannot be\n      // focused. Create a fake thing to focus on. If the backdrop was _before_ the dialog, this\n      // would not be needed - clicks would move the implicit cursor there.\n      var fake = document.createElement('div');\n      this.dialog_.insertBefore(fake, this.dialog_.firstChild);\n      fake.tabIndex = -1;\n      fake.focus();\n      this.dialog_.removeChild(fake);\n    } else {\n      this.dialog_.focus();\n    }\n\n    var redirectedEvent = document.createEvent('MouseEvents');\n    redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window,\n        e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey,\n        e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);\n    this.dialog_.dispatchEvent(redirectedEvent);\n    e.stopPropagation();\n  },\n\n  /**\n   * Focuses on the first focusable element within the dialog. This will always blur the current\n   * focus, even if nothing within the dialog is found.\n   */\n  focus_: function() {\n    // Find element with `autofocus` attribute, or fall back to the first form/tabindex control.\n    var target = this.dialog_.querySelector('[autofocus]:not([disabled])');\n    if (!target && this.dialog_.tabIndex >= 0) {\n      target = this.dialog_;\n    }\n    if (!target) {\n      // Note that this is 'any focusable area'. This list is probably not exhaustive, but the\n      // alternative involves stepping through and trying to focus everything.\n      var opts = ['button', 'input', 'keygen', 'select', 'textarea'];\n      var query = opts.map(function(el) {\n        return el + ':not([disabled])';\n      });\n      // TODO(samthor): tabindex values that are not numeric are not focusable.\n      query.push('[tabindex]:not([disabled]):not([tabindex=\"\"])');  // tabindex != \"\", not disabled\n      target = this.dialog_.querySelector(query.join(', '));\n    }\n    safeBlur(document.activeElement);\n    target && target.focus();\n  },\n\n  /**\n   * Sets the zIndex for the backdrop and dialog.\n   *\n   * @param {number} dialogZ\n   * @param {number} backdropZ\n   */\n  updateZIndex: function(dialogZ, backdropZ) {\n    if (dialogZ < backdropZ) {\n      throw new Error('dialogZ should never be < backdropZ');\n    }\n    this.dialog_.style.zIndex = dialogZ;\n    this.backdrop_.style.zIndex = backdropZ;\n  },\n\n  /**\n   * Shows the dialog. If the dialog is already open, this does nothing.\n   */\n  show: function() {\n    if (!this.dialog_.open) {\n      this.setOpen(true);\n      this.focus_();\n    }\n  },\n\n  /**\n   * Show this dialog modally.\n   */\n  showModal: function() {\n    if (this.dialog_.hasAttribute('open')) {\n      throw new Error('Failed to execute \\'showModal\\' on dialog: The element is already open, and therefore cannot be opened modally.');\n    }\n    if (!document.body.contains(this.dialog_)) {\n      throw new Error('Failed to execute \\'showModal\\' on dialog: The element is not in a Document.');\n    }\n    if (!dialogPolyfill.dm.pushDialog(this)) {\n      throw new Error('Failed to execute \\'showModal\\' on dialog: There are too many open modal dialogs.');\n    }\n\n    if (createsStackingContext(this.dialog_.parentElement)) {\n      console.warn('A dialog is being shown inside a stacking context. ' +\n          'This may cause it to be unusable. For more information, see this link: ' +\n          'https://github.com/GoogleChrome/dialog-polyfill/#stacking-context');\n    }\n\n    this.setOpen(true);\n    this.openAsModal_ = true;\n\n    // Optionally center vertically, relative to the current viewport.\n    if (dialogPolyfill.needsCentering(this.dialog_)) {\n      dialogPolyfill.reposition(this.dialog_);\n      this.replacedStyleTop_ = true;\n    } else {\n      this.replacedStyleTop_ = false;\n    }\n\n    // Insert backdrop.\n    this.dialog_.parentNode.insertBefore(this.backdrop_, this.dialog_.nextSibling);\n\n    // Focus on whatever inside the dialog.\n    this.focus_();\n  },\n\n  /**\n   * Closes this HTMLDialogElement. This is optional vs clearing the open\n   * attribute, however this fires a 'close' event.\n   *\n   * @param {string=} opt_returnValue to use as the returnValue\n   */\n  close: function(opt_returnValue) {\n    if (!this.dialog_.hasAttribute('open')) {\n      throw new Error('Failed to execute \\'close\\' on dialog: The element does not have an \\'open\\' attribute, and therefore cannot be closed.');\n    }\n    this.setOpen(false);\n\n    // Leave returnValue untouched in case it was set directly on the element\n    if (opt_returnValue !== undefined) {\n      this.dialog_.returnValue = opt_returnValue;\n    }\n\n    // Triggering \"close\" event for any attached listeners on the <dialog>.\n    var closeEvent = new supportCustomEvent('close', {\n      bubbles: false,\n      cancelable: false\n    });\n    this.dialog_.dispatchEvent(closeEvent);\n  }\n\n};\n\nvar dialogPolyfill = {};\n\ndialogPolyfill.reposition = function(element) {\n  var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;\n  var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2;\n  element.style.top = Math.max(scrollTop, topValue) + 'px';\n};\n\ndialogPolyfill.isInlinePositionSetByStylesheet = function(element) {\n  for (var i = 0; i < document.styleSheets.length; ++i) {\n    var styleSheet = document.styleSheets[i];\n    var cssRules = null;\n    // Some browsers throw on cssRules.\n    try {\n      cssRules = styleSheet.cssRules;\n    } catch (e) {}\n    if (!cssRules) { continue; }\n    for (var j = 0; j < cssRules.length; ++j) {\n      var rule = cssRules[j];\n      var selectedNodes = null;\n      // Ignore errors on invalid selector texts.\n      try {\n        selectedNodes = document.querySelectorAll(rule.selectorText);\n      } catch(e) {}\n      if (!selectedNodes || !inNodeList(selectedNodes, element)) {\n        continue;\n      }\n      var cssTop = rule.style.getPropertyValue('top');\n      var cssBottom = rule.style.getPropertyValue('bottom');\n      if ((cssTop && cssTop !== 'auto') || (cssBottom && cssBottom !== 'auto')) {\n        return true;\n      }\n    }\n  }\n  return false;\n};\n\ndialogPolyfill.needsCentering = function(dialog) {\n  var computedStyle = window.getComputedStyle(dialog);\n  if (computedStyle.position !== 'absolute') {\n    return false;\n  }\n\n  // We must determine whether the top/bottom specified value is non-auto.  In\n  // WebKit/Blink, checking computedStyle.top == 'auto' is sufficient, but\n  // Firefox returns the used value. So we do this crazy thing instead: check\n  // the inline style and then go through CSS rules.\n  if ((dialog.style.top !== 'auto' && dialog.style.top !== '') ||\n      (dialog.style.bottom !== 'auto' && dialog.style.bottom !== '')) {\n    return false;\n  }\n  return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog);\n};\n\n/**\n * @param {!Element} element to force upgrade\n */\ndialogPolyfill.forceRegisterDialog = function(element) {\n  if (window.HTMLDialogElement || element.showModal) {\n    console.warn('This browser already supports <dialog>, the polyfill ' +\n        'may not work correctly', element);\n  }\n  if (element.localName !== 'dialog') {\n    throw new Error('Failed to register dialog: The element is not a dialog.');\n  }\n  new dialogPolyfillInfo(/** @type {!HTMLDialogElement} */ (element));\n};\n\n/**\n * @param {!Element} element to upgrade, if necessary\n */\ndialogPolyfill.registerDialog = function(element) {\n  if (!element.showModal) {\n    dialogPolyfill.forceRegisterDialog(element);\n  }\n};\n\n/**\n * @constructor\n */\ndialogPolyfill.DialogManager = function() {\n  /** @type {!Array<!dialogPolyfillInfo>} */\n  this.pendingDialogStack = [];\n\n  var checkDOM = this.checkDOM_.bind(this);\n\n  // The overlay is used to simulate how a modal dialog blocks the document.\n  // The blocking dialog is positioned on top of the overlay, and the rest of\n  // the dialogs on the pending dialog stack are positioned below it. In the\n  // actual implementation, the modal dialog stacking is controlled by the\n  // top layer, where z-index has no effect.\n  this.overlay = document.createElement('div');\n  this.overlay.className = '_dialog_overlay';\n  this.overlay.addEventListener('click', function(e) {\n    this.forwardTab_ = undefined;\n    e.stopPropagation();\n    checkDOM([]);  // sanity-check DOM\n  }.bind(this));\n\n  this.handleKey_ = this.handleKey_.bind(this);\n  this.handleFocus_ = this.handleFocus_.bind(this);\n\n  this.zIndexLow_ = 100000;\n  this.zIndexHigh_ = 100000 + 150;\n\n  this.forwardTab_ = undefined;\n\n  if ('MutationObserver' in window) {\n    this.mo_ = new MutationObserver(function(records) {\n      var removed = [];\n      records.forEach(function(rec) {\n        for (var i = 0, c; c = rec.removedNodes[i]; ++i) {\n          if (!(c instanceof Element)) {\n            continue;\n          } else if (c.localName === 'dialog') {\n            removed.push(c);\n          }\n          removed = removed.concat(c.querySelectorAll('dialog'));\n        }\n      });\n      removed.length && checkDOM(removed);\n    });\n  }\n};\n\n/**\n * Called on the first modal dialog being shown. Adds the overlay and related\n * handlers.\n */\ndialogPolyfill.DialogManager.prototype.blockDocument = function() {\n  document.documentElement.addEventListener('focus', this.handleFocus_, true);\n  document.addEventListener('keydown', this.handleKey_);\n  this.mo_ && this.mo_.observe(document, {childList: true, subtree: true});\n};\n\n/**\n * Called on the first modal dialog being removed, i.e., when no more modal\n * dialogs are visible.\n */\ndialogPolyfill.DialogManager.prototype.unblockDocument = function() {\n  document.documentElement.removeEventListener('focus', this.handleFocus_, true);\n  document.removeEventListener('keydown', this.handleKey_);\n  this.mo_ && this.mo_.disconnect();\n};\n\n/**\n * Updates the stacking of all known dialogs.\n */\ndialogPolyfill.DialogManager.prototype.updateStacking = function() {\n  var zIndex = this.zIndexHigh_;\n\n  for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {\n    dpi.updateZIndex(--zIndex, --zIndex);\n    if (i === 0) {\n      this.overlay.style.zIndex = --zIndex;\n    }\n  }\n\n  // Make the overlay a sibling of the dialog itself.\n  var last = this.pendingDialogStack[0];\n  if (last) {\n    var p = last.dialog.parentNode || document.body;\n    p.appendChild(this.overlay);\n  } else if (this.overlay.parentNode) {\n    this.overlay.parentNode.removeChild(this.overlay);\n  }\n};\n\n/**\n * @param {Element} candidate to check if contained or is the top-most modal dialog\n * @return {boolean} whether candidate is contained in top dialog\n */\ndialogPolyfill.DialogManager.prototype.containedByTopDialog_ = function(candidate) {\n  while (candidate = findNearestDialog(candidate)) {\n    for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {\n      if (dpi.dialog === candidate) {\n        return i === 0;  // only valid if top-most\n      }\n    }\n    candidate = candidate.parentElement;\n  }\n  return false;\n};\n\ndialogPolyfill.DialogManager.prototype.handleFocus_ = function(event) {\n  if (this.containedByTopDialog_(event.target)) { return; }\n\n  if (document.activeElement === document.documentElement) { return; }\n\n  event.preventDefault();\n  event.stopPropagation();\n  safeBlur(/** @type {Element} */ (event.target));\n\n  if (this.forwardTab_ === undefined) { return; }  // move focus only from a tab key\n\n  var dpi = this.pendingDialogStack[0];\n  var dialog = dpi.dialog;\n  var position = dialog.compareDocumentPosition(event.target);\n  if (position & Node.DOCUMENT_POSITION_PRECEDING) {\n    if (this.forwardTab_) {\n      // forward\n      dpi.focus_();\n    } else if (event.target !== document.documentElement) {\n      // backwards if we're not already focused on <html>\n      document.documentElement.focus();\n    }\n  }\n\n  return false;\n};\n\ndialogPolyfill.DialogManager.prototype.handleKey_ = function(event) {\n  this.forwardTab_ = undefined;\n  if (event.keyCode === 27) {\n    event.preventDefault();\n    event.stopPropagation();\n    var cancelEvent = new supportCustomEvent('cancel', {\n      bubbles: false,\n      cancelable: true\n    });\n    var dpi = this.pendingDialogStack[0];\n    if (dpi && dpi.dialog.dispatchEvent(cancelEvent)) {\n      dpi.dialog.close();\n    }\n  } else if (event.keyCode === 9) {\n    this.forwardTab_ = !event.shiftKey;\n  }\n};\n\n/**\n * Finds and downgrades any known modal dialogs that are no longer displayed. Dialogs that are\n * removed and immediately readded don't stay modal, they become normal.\n *\n * @param {!Array<!HTMLDialogElement>} removed that have definitely been removed\n */\ndialogPolyfill.DialogManager.prototype.checkDOM_ = function(removed) {\n  // This operates on a clone because it may cause it to change. Each change also calls\n  // updateStacking, which only actually needs to happen once. But who removes many modal dialogs\n  // at a time?!\n  var clone = this.pendingDialogStack.slice();\n  clone.forEach(function(dpi) {\n    if (removed.indexOf(dpi.dialog) !== -1) {\n      dpi.downgradeModal();\n    } else {\n      dpi.maybeHideModal();\n    }\n  });\n};\n\n/**\n * @param {!dialogPolyfillInfo} dpi\n * @return {boolean} whether the dialog was allowed\n */\ndialogPolyfill.DialogManager.prototype.pushDialog = function(dpi) {\n  var allowed = (this.zIndexHigh_ - this.zIndexLow_) / 2 - 1;\n  if (this.pendingDialogStack.length >= allowed) {\n    return false;\n  }\n  if (this.pendingDialogStack.unshift(dpi) === 1) {\n    this.blockDocument();\n  }\n  this.updateStacking();\n  return true;\n};\n\n/**\n * @param {!dialogPolyfillInfo} dpi\n */\ndialogPolyfill.DialogManager.prototype.removeDialog = function(dpi) {\n  var index = this.pendingDialogStack.indexOf(dpi);\n  if (index === -1) { return; }\n\n  this.pendingDialogStack.splice(index, 1);\n  if (this.pendingDialogStack.length === 0) {\n    this.unblockDocument();\n  }\n  this.updateStacking();\n};\n\ndialogPolyfill.dm = new dialogPolyfill.DialogManager();\ndialogPolyfill.formSubmitter = null;\ndialogPolyfill.useValue = null;\n\n/**\n * Installs global handlers, such as click listers and native method overrides. These are needed\n * even if a no dialog is registered, as they deal with <form method=\"dialog\">.\n */\nif (window.HTMLDialogElement === undefined) {\n\n  /**\n   * If HTMLFormElement translates method=\"DIALOG\" into 'get', then replace the descriptor with\n   * one that returns the correct value.\n   */\n  var testForm = document.createElement('form');\n  testForm.setAttribute('method', 'dialog');\n  if (testForm.method !== 'dialog') {\n    var methodDescriptor = Object.getOwnPropertyDescriptor(HTMLFormElement.prototype, 'method');\n    if (methodDescriptor) {\n      // nb. Some older iOS and older PhantomJS fail to return the descriptor. Don't do anything\n      // and don't bother to update the element.\n      var realGet = methodDescriptor.get;\n      methodDescriptor.get = function() {\n        if (isFormMethodDialog(this)) {\n          return 'dialog';\n        }\n        return realGet.call(this);\n      };\n      var realSet = methodDescriptor.set;\n      methodDescriptor.set = function(v) {\n        if (typeof v === 'string' && v.toLowerCase() === 'dialog') {\n          return this.setAttribute('method', v);\n        }\n        return realSet.call(this, v);\n      };\n      Object.defineProperty(HTMLFormElement.prototype, 'method', methodDescriptor);\n    }\n  }\n\n  /**\n   * Global 'click' handler, to capture the <input type=\"submit\"> or <button> element which has\n   * submitted a <form method=\"dialog\">. Needed as Safari and others don't report this inside\n   * document.activeElement.\n   */\n  document.addEventListener('click', function(ev) {\n    dialogPolyfill.formSubmitter = null;\n    dialogPolyfill.useValue = null;\n    if (ev.defaultPrevented) { return; }  // e.g. a submit which prevents default submission\n\n    var target = /** @type {Element} */ (ev.target);\n    if (!target || !isFormMethodDialog(target.form)) { return; }\n\n    var valid = (target.type === 'submit' && ['button', 'input'].indexOf(target.localName) > -1);\n    if (!valid) {\n      if (!(target.localName === 'input' && target.type === 'image')) { return; }\n      // this is a <input type=\"image\">, which can submit forms\n      dialogPolyfill.useValue = ev.offsetX + ',' + ev.offsetY;\n    }\n\n    var dialog = findNearestDialog(target);\n    if (!dialog) { return; }\n\n    dialogPolyfill.formSubmitter = target;\n\n  }, false);\n\n  /**\n   * Replace the native HTMLFormElement.submit() method, as it won't fire the\n   * submit event and give us a chance to respond.\n   */\n  var nativeFormSubmit = HTMLFormElement.prototype.submit;\n  var replacementFormSubmit = function () {\n    if (!isFormMethodDialog(this)) {\n      return nativeFormSubmit.call(this);\n    }\n    var dialog = findNearestDialog(this);\n    dialog && dialog.close();\n  };\n  HTMLFormElement.prototype.submit = replacementFormSubmit;\n\n  /**\n   * Global form 'dialog' method handler. Closes a dialog correctly on submit\n   * and possibly sets its return value.\n   */\n  document.addEventListener('submit', function(ev) {\n    if (ev.defaultPrevented) { return; }  // e.g. a submit which prevents default submission\n\n    var form = /** @type {HTMLFormElement} */ (ev.target);\n    if (!isFormMethodDialog(form)) { return; }\n    ev.preventDefault();\n\n    var dialog = findNearestDialog(form);\n    if (!dialog) { return; }\n\n    // Forms can only be submitted via .submit() or a click (?), but anyway: sanity-check that\n    // the submitter is correct before using its value as .returnValue.\n    var s = dialogPolyfill.formSubmitter;\n    if (s && s.form === form) {\n      dialog.close(dialogPolyfill.useValue || s.value);\n    } else {\n      dialog.close();\n    }\n    dialogPolyfill.formSubmitter = null;\n\n  }, false);\n}\n\nexport default dialogPolyfill;\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nexport function registerHeaderListeners(): void {\n  const header = document.querySelector('.js-header');\n  const menuButtons = document.querySelectorAll('.js-headerMenuButton');\n  menuButtons.forEach(button => {\n    button.addEventListener('click', e => {\n      e.preventDefault();\n      header?.classList.toggle('is-active');\n      button.setAttribute('aria-expanded', String(header?.classList.contains('is-active')));\n    });\n  });\n\n  const scrim = document.querySelector('.js-scrim');\n  scrim?.addEventListener('click', e => {\n    e.preventDefault();\n    header?.classList.remove('is-active');\n    menuButtons.forEach(button => {\n      button.setAttribute('aria-expanded', String(header?.classList.contains('is-active')));\n    });\n  });\n}\n\nexport function registerSearchFormListeners(): void {\n  const searchForm = document.querySelector('.js-searchForm');\n  const expandSearch = document.querySelector('.js-expandSearch');\n  const input = searchForm?.querySelector('input');\n  const headerLogo = document.querySelector('.js-headerLogo');\n  const menuButton = document.querySelector('.js-headerMenuButton');\n  expandSearch?.addEventListener('click', () => {\n    searchForm?.classList.add('go-SearchForm--expanded');\n    headerLogo?.classList.add('go-Header-logo--hidden');\n    menuButton?.classList.add('go-Header-navOpen--hidden');\n    input?.focus();\n  });\n  document?.addEventListener('click', e => {\n    if (!searchForm?.contains(e.target as Node)) {\n      searchForm?.classList.remove('go-SearchForm--expanded');\n      headerLogo?.classList.remove('go-Header-logo--hidden');\n      menuButton?.classList.remove('go-Header-navOpen--hidden');\n    }\n  });\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * Carousel Controller adds event listeners, accessibilty enhancements, and\n * control elements to a carousel component.\n */\nexport class CarouselController {\n  /**\n   * slides is a collection of slides in the carousel.\n   */\n  private slides: HTMLLIElement[];\n  /**\n   * dots is a collection of dot navigation controls, added to the carousel\n   * by this controller.\n   */\n  private dots: HTMLElement[];\n  /**\n   * liveRegion is a visually hidden element that notifies assitive devices\n   * of visual changes to the carousel. They are added to the carousel by\n   * this controller.\n   */\n  private liveRegion: HTMLElement;\n  /**\n   * activeIndex is the 0-index of the currently active slide.\n   */\n  private activeIndex: number;\n\n  constructor(private el: HTMLElement) {\n    this.slides = Array.from(el.querySelectorAll('.go-Carousel-slide'));\n    this.dots = [];\n    this.liveRegion = document.createElement('div');\n    this.activeIndex = Number(el.getAttribute('data-slide-index') ?? 0);\n\n    this.initSlides();\n    this.initArrows();\n    this.initDots();\n    this.initLiveRegion();\n  }\n\n  private initSlides() {\n    for (const [i, v] of this.slides.entries()) {\n      if (i === this.activeIndex) continue;\n      v.setAttribute('aria-hidden', 'true');\n    }\n  }\n\n  private initArrows() {\n    const arrows = document.createElement('ul');\n    arrows.classList.add('go-Carousel-arrows');\n    arrows.innerHTML = `\n      <li>\n        <button class=\"go-Carousel-prevSlide\" aria-label=\"Go to previous slide\">\n          <img class=\"go-Icon\" height=\"24\" width=\"24\" src=\"/static/shared/icon/arrow_left_gm_grey_24dp.svg\" alt=\"\">\n        </button>\n      </li>\n      <li>\n        <button class=\"go-Carousel-nextSlide\" aria-label=\"Go to next slide\">\n          <img class=\"go-Icon\" height=\"24\" width=\"24\" src=\"/static/shared/icon/arrow_right_gm_grey_24dp.svg\" alt=\"\">\n        </button>\n      </li>\n    `;\n    arrows\n      .querySelector('.go-Carousel-prevSlide')\n      ?.addEventListener('click', () => this.setActive(this.activeIndex - 1));\n    arrows\n      .querySelector('.go-Carousel-nextSlide')\n      ?.addEventListener('click', () => this.setActive(this.activeIndex + 1));\n    this.el.append(arrows);\n  }\n\n  private initDots() {\n    const dots = document.createElement('ul');\n    dots.classList.add('go-Carousel-dots');\n    for (let i = 0; i < this.slides.length; i++) {\n      const li = document.createElement('li');\n      const button = document.createElement('button');\n      button.classList.add('go-Carousel-dot');\n      if (i === this.activeIndex) {\n        button.classList.add('go-Carousel-dot--active');\n      }\n      button.innerHTML = `<span class=\"go-Carousel-obscured\">Slide ${i + 1}</span>`;\n      button.addEventListener('click', () => this.setActive(i));\n      li.append(button);\n      dots.append(li);\n      this.dots.push(button);\n    }\n    this.el.append(dots);\n  }\n\n  private initLiveRegion() {\n    this.liveRegion.setAttribute('aria-live', 'polite');\n    this.liveRegion.setAttribute('aria-atomic', 'true');\n    this.liveRegion.setAttribute('class', 'go-Carousel-obscured');\n    this.liveRegion.textContent = `Slide ${this.activeIndex + 1} of ${this.slides.length}`;\n    this.el.appendChild(this.liveRegion);\n  }\n\n  private setActive = (index: number) => {\n    this.activeIndex = (index + this.slides.length) % this.slides.length;\n    this.el.setAttribute('data-slide-index', String(this.activeIndex));\n    for (const d of this.dots) {\n      d.classList.remove('go-Carousel-dot--active');\n    }\n    this.dots[this.activeIndex].classList.add('go-Carousel-dot--active');\n    for (const s of this.slides) {\n      s.setAttribute('aria-hidden', 'true');\n    }\n    this.slides[this.activeIndex].removeAttribute('aria-hidden');\n    this.liveRegion.textContent = 'Slide ' + (this.activeIndex + 1) + ' of ' + this.slides.length;\n  };\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * This class decorates an element to copy arbitrary data attached via a data-\n * attribute to the clipboard.\n */\nexport class ClipboardController {\n  /**\n   * The data to be copied to the clipboard.\n   */\n  private data: string;\n\n  /**\n   * @param el The element that will trigger copying text to the clipboard. The text is\n   * expected to be within its data-to-copy attribute.\n   */\n  constructor(private el: HTMLButtonElement) {\n    this.data = el.dataset['toCopy'] ?? el.innerText;\n    // if data-to-copy is empty and the button is part of an input group\n    // capture the value of the input.\n    if (!this.data && el.parentElement?.classList.contains('go-InputGroup')) {\n      this.data = (this.data || el.parentElement?.querySelector('input')?.value) ?? '';\n    }\n    el.addEventListener('click', e => this.handleCopyClick(e));\n  }\n\n  /**\n   * Handles when the primary element is clicked.\n   */\n  handleCopyClick(e: MouseEvent): void {\n    e.preventDefault();\n    const TOOLTIP_SHOW_DURATION_MS = 1000;\n\n    // This API is not available on iOS.\n    if (!navigator.clipboard) {\n      this.showTooltipText('Unable to copy', TOOLTIP_SHOW_DURATION_MS);\n      return;\n    }\n    navigator.clipboard\n      .writeText(this.data)\n      .then(() => {\n        this.showTooltipText('Copied!', TOOLTIP_SHOW_DURATION_MS);\n      })\n      .catch(() => {\n        this.showTooltipText('Unable to copy', TOOLTIP_SHOW_DURATION_MS);\n      });\n  }\n\n  /**\n   * Shows the given text in a tooltip for a specified amount of time, in milliseconds.\n   */\n  showTooltipText(text: string, durationMs: number): void {\n    this.el.setAttribute('data-tooltip', text);\n    setTimeout(() => this.el.setAttribute('data-tooltip', ''), durationMs);\n  }\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * ToolTipController handles closing tooltips on external clicks.\n */\nexport class ToolTipController {\n  constructor(private el: HTMLDetailsElement) {\n    document.addEventListener('click', e => {\n      const insideTooltip = this.el.contains(e.target as Element);\n      if (!insideTooltip) {\n        this.el.removeAttribute('open');\n      }\n    });\n  }\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { TreeNavController } from './tree.js';\n\nexport class SelectNavController {\n  constructor(private el: Element) {\n    this.el.addEventListener('change', e => {\n      const target = e.target as HTMLSelectElement;\n      let href = target.value;\n      if (!target.value.startsWith('/')) {\n        href = '/' + href;\n      }\n      window.location.href = href;\n    });\n  }\n}\n\nexport function makeSelectNav(tree: TreeNavController): HTMLLabelElement {\n  const label = document.createElement('label');\n  label.classList.add('go-Label');\n  label.setAttribute('aria-label', 'Menu');\n  const select = document.createElement('select');\n  select.classList.add('go-Select', 'js-selectNav');\n  label.appendChild(select);\n  const outline = document.createElement('optgroup');\n  outline.label = 'Outline';\n  select.appendChild(outline);\n  const groupMap: Record<string, HTMLOptGroupElement> = {};\n  let group: HTMLOptGroupElement;\n  for (const t of tree.treeitems) {\n    if (Number(t.depth) > 4) continue;\n    if (t.groupTreeitem) {\n      group = groupMap[t.groupTreeitem.label];\n      if (!group) {\n        group = groupMap[t.groupTreeitem.label] = document.createElement('optgroup');\n        group.label = t.groupTreeitem.label;\n        select.appendChild(group);\n      }\n    } else {\n      group = outline;\n    }\n    const o = document.createElement('option');\n    o.label = t.label;\n    o.textContent = t.label;\n    o.value = (t.el as HTMLAnchorElement).href.replace(window.location.origin, '').replace('/', '');\n    group.appendChild(o);\n  }\n  tree.addObserver(t => {\n    const hash = (t.el as HTMLAnchorElement).hash;\n    const value = select.querySelector<HTMLOptionElement>(`[value$=\"${hash}\"]`)?.value;\n    if (value) {\n      select.value = value;\n    }\n  }, 50);\n  return label;\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * ModalController registers a dialog element with the polyfill if\n * necessary for the current browser, add adds event listeners to\n * close and open modals.\n */\nexport class ModalController {\n  constructor(private el: HTMLDialogElement) {\n    // Only load the dialog polyfill if necessary for the environment.\n    if (!window.HTMLDialogElement && !el.showModal) {\n      import('../../../third_party/dialog-polyfill/dialog-polyfill.esm.js').then(\n        ({ default: polyfill }) => {\n          polyfill.registerDialog(el);\n        }\n      );\n    }\n    const id = el.id;\n    const button = document.querySelector<HTMLButtonElement>(`[aria-controls=\"${id}\"]`);\n    if (button) {\n      button.addEventListener('click', () => {\n        if (this.el.showModal) {\n          this.el.showModal();\n        } else {\n          this.el.open = true;\n        }\n        el.querySelector('input')?.focus();\n      });\n    }\n    for (const close of this.el.querySelectorAll<HTMLButtonElement>('[data-modal-close]')) {\n      close.addEventListener('click', () => {\n        if (this.el.close) {\n          this.el.close();\n        } else {\n          this.el.open = false;\n        }\n      });\n    }\n  }\n}\n", "interface TagManagerEvent {\n  /**\n   * event is the name of the event, used to filter events in\n   * Google Analytics.\n   */\n  event: string;\n\n  /**\n   * event_category is a name that you supply as a way to group objects\n   * that to analyze. Typically, you will use the same category name\n   * multiple times over related UI elements (buttons, links, etc).\n   */\n  event_category?: string;\n\n  /**\n   * event_action is used to name the type of event or interaction you\n   * want to measure for a particular web object. For example, with a\n   * single \"form\" category, you can analyze a number of specific events\n   * with this parameter, such as: form entered, form submitted.\n   */\n  event_action?: string;\n\n  /**\n   * event_label provide additional information for events that you want\n   * to analyze, such as the text label of a link.\n   */\n  event_label?: string;\n\n  /**\n   * gtm.start is used to initialize Google Tag Manager.\n   */\n  'gtm.start'?: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ndeclare global {\n  interface Window {\n    dataLayer?: (TagManagerEvent | VoidFunction)[];\n    ga?: unknown;\n  }\n}\n\n/**\n * track sends events to Google Tag Manager.\n */\nexport function track(\n  event: string | TagManagerEvent,\n  category?: string,\n  action?: string,\n  label?: string\n): void {\n  window.dataLayer ??= [];\n  if (typeof event === 'string') {\n    window.dataLayer.push({\n      event,\n      event_category: category,\n      event_action: action,\n      event_label: label,\n    });\n  } else {\n    window.dataLayer.push(event);\n  }\n}\n\n/**\n * func adds functions to run sequentionally after\n * Google Tag Manager is ready.\n */\nexport function func(fn: () => void): void {\n  window.dataLayer ??= [];\n  window.dataLayer.push(fn);\n}\n", "/*!\n * @license\n * Copyright 2019-2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { track } from '../analytics/analytics';\n\n/**\n * Options are keyhandler callback options.\n */\ninterface Options {\n  /**\n   * target is the element the key event should filter on. The\n   * default target is the document.\n   */\n  target?: Element;\n\n  /**\n   * withMeta specifies if the event callback should fire when\n   * the key is pressed with a meta key (ctrl, alt, etc). By\n   * default meta keypresses are ignored.\n   */\n  withMeta?: boolean;\n}\n\n/**\n * KeyHandler is the config for a keyboard event callback.\n */\ninterface KeyHandler extends Options {\n  description: string;\n  callback: (e: KeyboardEvent) => void;\n}\n\n/**\n * KeyboardController controls event callbacks for sitewide\n * keyboard events. Multiple callbacks can be registered for\n * a single key and by default the controller ignores events\n * for text input targets.\n */\nclass KeyboardController {\n  handlers: Record<string, Set<KeyHandler>>;\n\n  constructor() {\n    this.handlers = {};\n    document.addEventListener('keydown', e => this.handleKeyPress(e));\n  }\n\n  /**\n   * on registers keyboard event callbacks.\n   * @param key the key to register.\n   * @param description name of the event.\n   * @param callback event callback.\n   * @param options set target and withMeta options to override the default behaviors.\n   */\n  on(key: string, description: string, callback: (e: KeyboardEvent) => void, options?: Options) {\n    this.handlers[key] ??= new Set();\n    this.handlers[key].add({ description, callback, ...options });\n    return this;\n  }\n\n  private handleKeyPress(e: KeyboardEvent) {\n    for (const handler of this.handlers[e.key.toLowerCase()] ?? new Set()) {\n      if (handler.target && handler.target !== e.target) {\n        return;\n      }\n      const t = e.target as HTMLElement | null;\n      if (\n        !handler.target &&\n        (t?.tagName === 'INPUT' || t?.tagName === 'SELECT' || t?.tagName === 'TEXTAREA')\n      ) {\n        return;\n      }\n      if (t?.isContentEditable) {\n        return;\n      }\n      if (\n        (handler.withMeta && !(e.ctrlKey || e.metaKey)) ||\n        (!handler.withMeta && (e.ctrlKey || e.metaKey))\n      ) {\n        return;\n      }\n      track('keypress', 'hotkeys', `${e.key} pressed`, handler.description);\n      handler.callback(e);\n    }\n  }\n}\n\nexport const keyboard = new KeyboardController();\n", "/**\n * @license\n * Copyright 2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { registerHeaderListeners, registerSearchFormListeners } from 'static/shared/header/header';\nimport { CarouselController } from 'static/shared/carousel/carousel';\nimport { ClipboardController } from 'static/shared/clipboard/clipboard';\nimport { ToolTipController } from 'static/shared/tooltip/tooltip';\nimport { SelectNavController } from 'static/shared/outline/select';\nimport { ModalController } from 'static/shared/modal/modal';\n\nimport { keyboard } from 'static/shared/keyboard/keyboard';\nimport * as analytics from 'static/shared/analytics/analytics';\n\nregisterHeaderListeners();\nregisterSearchFormListeners();\n\nfor (const el of document.querySelectorAll<HTMLButtonElement>('.js-clipboard')) {\n  new ClipboardController(el);\n}\n\nfor (const el of document.querySelectorAll<HTMLDialogElement>('.js-modal')) {\n  new ModalController(el);\n}\n\nfor (const t of document.querySelectorAll<HTMLDetailsElement>('.js-tooltip')) {\n  new ToolTipController(t);\n}\n\nfor (const el of document.querySelectorAll<HTMLSelectElement>('.js-selectNav')) {\n  new SelectNavController(el);\n}\n\nfor (const el of document.querySelectorAll<HTMLSelectElement>('.js-carousel')) {\n  new CarouselController(el);\n}\n\n// Temporary shortcut for testing out the dark theme.\nkeyboard.on('t', 'toggle theme', () => {\n  toggleTheme();\n});\n\n// Pressing '/' focuses the search box\nkeyboard.on('/', 'focus search', e => {\n  const searchInput = Array.from(\n    document.querySelectorAll<HTMLInputElement>('.js-searchFocus')\n  ).pop();\n  // Favoring the Firefox quick find feature over search input\n  // focus. See: https://github.com/golang/go/issues/41093.\n  if (searchInput && !window.navigator.userAgent.includes('Firefox')) {\n    e.preventDefault();\n    searchInput.focus();\n  }\n});\n\n// Pressing 'y' changes the browser URL to the canonical URL\n// without triggering a reload.\nkeyboard.on('y', 'set canonical url', () => {\n  const canonicalURLPath = document.querySelector<HTMLDivElement>('.js-canonicalURLPath')?.dataset[\n    'canonicalUrlPath'\n  ];\n  if (canonicalURLPath && canonicalURLPath !== '') {\n    window.history.replaceState(null, '', canonicalURLPath);\n  }\n});\n\n/**\n * setupGoogleTagManager intializes Google Tag Manager.\n */\n(function setupGoogleTagManager() {\n  analytics.track({\n    'gtm.start': new Date().getTime(),\n    event: 'gtm.js',\n  });\n})();\n\n/**\n * removeUTMSource removes the utm_source GET parameter if present.\n * This is done using JavaScript, so that the utm_source is still\n * captured by Google Analytics.\n */\nfunction removeUTMSource() {\n  const urlParams = new URLSearchParams(window.location.search);\n  const utmSource = urlParams.get('utm_source');\n  if (utmSource !== 'gopls' && utmSource !== 'godoc' && utmSource !== 'pkggodev') {\n    return;\n  }\n\n  /** Strip the utm_source query parameter and replace the URL. **/\n  const newURL = new URL(window.location.href);\n  urlParams.delete('utm_source');\n  newURL.search = urlParams.toString();\n  window.history.replaceState(null, '', newURL.toString());\n}\n\nif (document.querySelector<HTMLElement>('.js-gtmID')?.dataset.gtmid && window.dataLayer) {\n  analytics.func(function () {\n    removeUTMSource();\n  });\n} else {\n  removeUTMSource();\n}\n\nfor (const el of document.querySelectorAll('.js-toggleTheme')) {\n  el.addEventListener('click', () => {\n    toggleTheme();\n  });\n}\n\n/**\n * toggleTheme switches the preferred color scheme between auto, light, and dark.\n */\nfunction toggleTheme() {\n  let nextTheme = 'dark';\n  const theme = document.documentElement.getAttribute('data-theme');\n  if (theme === 'dark') {\n    nextTheme = 'light';\n  } else if (theme === 'light') {\n    nextTheme = 'auto';\n  }\n  document.documentElement.setAttribute('data-theme', nextTheme);\n  document.cookie = `prefers-color-scheme=${nextTheme};path=/;max-age=31536000;`;\n}\n"],
+  "mappings": "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",
   "names": []
 }
diff --git a/static/frontend/frontend.min.css b/static/frontend/frontend.min.css
index 951924c..dc7febb 100644
--- a/static/frontend/frontend.min.css
+++ b/static/frontend/frontend.min.css
@@ -3,5 +3,5 @@
  * Use of this source code is governed by a BSD-style
  * license that can be found in the LICENSE file.
  */
-html,body,button,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,hr,input,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,dialog,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font:inherit;font-size:100%;margin:0;padding:0;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:"";content:none}table{border-collapse:collapse;border-spacing:0}*,:before,:after{box-sizing:border-box}body{color:var(--color-text);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";font-size:1rem;line-height:normal}h1{font-size:1.5rem}h2{font-size:1.375rem}h3{font-size:1.25rem}h4{font-size:1.125rem}h5{font-size:1rem}h6{font-size:.875rem}h1,h2,h3,h4{font-weight:600;line-height:1.25em;word-break:break-word}h5,h6{font-weight:500;line-height:1.3em;word-break:break-word}hr{border:none;border-bottom:var(--border);margin:0;width:100%}p{font-size:1rem;line-height:1.5rem;max-width:60rem}strong{font-weight:600}.go-textSubtle{color:var(--color-text-subtle)}.go-textTitle{font-size:1.125rem;font-weight:600;line-height:1.25rem}.go-textLabel{font-size:.875rem;font-weight:600;line-height:1rem}.go-textPagination{font-size:.875rem;line-height:1rem}code,pre,textarea.code{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:.875rem;line-height:1.5em}pre,textarea.code{background-color:var(--color-background-accented);border:var(--border);border-radius:var(--border-radius);color:var(--color-text);overflow-x:auto;padding:.625rem;tab-size:4;white-space:pre}button,input,select,textarea{font:inherit}a,a:link,a:visited{color:var(--color-brand-primary);text-decoration:none}a:hover,a:hover>*{color:var(--color-brand-primary);text-decoration:underline}button:focus:not([disabled]){border-color:var(--color-brand-primary);-webkit-box-shadow:var(--focus-box-shadow);box-shadow:var(--focus-box-shadow);outline:transparent}.go-Button{align-items:center;background-color:var(--color-button);border:.0625rem solid transparent;border-radius:var(--border-radius);color:var(--color-button-text);cursor:pointer;display:inline-flex;font-weight:500;gap:.25rem}.go-Button:not(.go-Button--inline){padding:.5rem}.go-Button--accented{background-color:var(--color-button-accented);color:var(--color-button-accented-text)}.go-Button--inverted,.go-Button--text,.go-Button--inline{background-color:var(--color-button-inverted);color:var(--color-button-inverted-text)}.go-Button--inline{background-color:transparent}.go-Button--inverted{border:var(--border)}.go-Button:hover{box-shadow:var(--focus-box-shadow);filter:contrast(.95)}.go-Button--inline:hover{box-shadow:none;text-decoration:underline var(--color-button-inverted-text)}.go-Button:focus{filter:contrast(.95)}.go-Button--inverted:focus{border-color:var(--color-button-inverted-text)}.go-Button:active{box-shadow:none;filter:contrast(.85)}.go-Button:disabled{background-color:var(--color-button-disabled);box-shadow:none;color:var(--color-button-text-disabled);cursor:initial;filter:none;text-decoration:none}.go-Button--accented:disabled{background-color:var(--color-button-accented-disabled);color:var(--color-button-accented-text-disabled)}.go-Button--inverted:disabled,.go-Button--text:disabled,.go-Button--inline:disabled{background-color:var(--color-button-inverted-disabled);color:var(--color-button-inverted-text-disabled)}.go-Button--inline:disabled{background-color:transparent}.go-Breadcrumb ol{line-height:1.5rem;white-space:initial}.go-Breadcrumb li{align-items:center;color:var(--color-text-subtle);display:inline-flex;font-size:.875rem}.go-Breadcrumb li:not(:last-child):after{content:">";padding:0 .5rem}.go-Breadcrumb li:last-child>a{color:var(--color-text-subtle)}.go-Breadcrumb li>.go-Clipboard{margin:0 .5rem}.go-Carousel{align-items:center;display:flex;flex-direction:column;position:relative;text-align:center}.go-Carousel-slide{margin:.5rem 3rem}.go-Carousel-slide[aria-hidden]{display:none}.go-Carousel-prevSlide{left:0}.go-Carousel-nextSlide{right:0}.go-Carousel-prevSlide,.go-Carousel-nextSlide{background-color:transparent;border-radius:var(--border-radius);font-size:1.5rem;height:2.75rem;margin-top:-1.375rem;opacity:0;position:absolute;top:50%;width:2.75rem}.go-Carousel-prevSlide:hover,.go-Carousel-nextSlide:hover{background-color:var(--color-background-accented);cursor:pointer}.go-Carousel:hover .go-Carousel-prevSlide,.go-Carousel:hover .go-Carousel-nextSlide,.go-Carousel:focus-within .go-Carousel-prevSlide,.go-Carousel:focus-within .go-Carousel-nextSlide{opacity:1}.go-Carousel-dots{display:flex;font-size:.4375rem;gap:.5rem}.go-Carousel-dot{background-color:var(--color-border);border-radius:2rem;height:.4375rem;width:.4375rem}.go-Carousel-dot--active,.go-Carousel-dot:hover{background-color:var(--color-text-subtle)}.go-Carousel-obscured{border:0;clip:rect(0 0 0 0);height:.0625rem;margin:-.0625rem;overflow:hidden;padding:0;position:absolute;width:.0625rem}.go-Chip{background:var(--color-button);border:.0625rem solid var(--color-button);border-radius:1.25rem;color:var(--color-button-text);font-size:.75rem;padding:.125rem .625rem}.go-Chip--accented{background:var(--color-button-accented);border:.0625rem solid var(--color-button-accented);color:var(--color-button-accented-text)}.go-Chip--inverted{background:var(--color-button-inverted);border:var(--border);color:var(--color-text)}.go-Chip--highlighted{background:var(--color-background-highlighted-link);border-color:var(--color-background-highlighted-link);color:var(--color-brand-primary)}.go-Chip--alert{background:var(--pink);border:.0625rem solid var(--pink);color:var(--color-text-inverted)}.go-Chip--vuln{background:var(--pink-light);border:.0625rem solid var(--pink-light);color:var(--color-text-inverted)}.go-Chip--subtle{background-color:var(--color-background-accented);border-color:transparent;color:var(--color-text-subtle)}.go-Clipboard{position:relative}.go-Clipboard:before{background-color:var(--color-background-inverted);border-radius:var(--border-radius);color:var(--color-text-inverted);content:attr(data-tooltip);display:block;font-size:.9em;left:calc(100% + .125rem);padding:.25rem .3rem;position:absolute;text-transform:uppercase;top:.125rem;white-space:nowrap;z-index:1000}.go-Clipboard:after{border-bottom:.25rem solid transparent;border-left:0;border-right:.25rem solid var(--color-background-inverted);border-top:.25rem solid transparent;content:"";display:block;position:absolute;right:-.125rem;top:.5625rem;z-index:1000}.go-Clipboard:not([data-tooltip]):before,.go-Clipboard:not([data-tooltip]):after,.go-Clipboard[data-tooltip=""]:before,.go-Clipboard[data-tooltip=""]:after{display:none}:root{--gray-1: #202224;--gray-2: #3e4042;--gray-3: #555759;--gray-4: #6e7072;--gray-5: #848688;--gray-6: #aaacae;--gray-7: #c6c8ca;--gray-8: #dcdee0;--gray-9: #f0f1f2;--gray-10: #f8f8f8;--turq-light: #5dc9e2;--turq-med: #50b7e0;--turq-dark: #007d9c;--blue: #bfeaf4;--blue-light: #f2fafd;--black: #000;--green: #3a6e11;--green-light: #5fda64;--pink: #ce3262;--pink-light: #fdecf1;--purple: #542c7d;--slate: #253443;--white: #fff;--yellow: #fddd00;--yellow-light: #fff8cc;--color-brand-primary: var(--turq-dark);--color-background: var(--white);--color-background-inverted: var(--slate);--color-background-accented: var(--gray-10);--color-background-highlighted: var(--blue);--color-background-highlighted-link: var(--blue-light);--color-background-info: var(--gray-9);--color-background-warning: var(--yellow-light);--color-background-alert: var(--pink-light);--color-border: var(--gray-7);--color-text: var(--gray-1);--color-text-subtle: var(--gray-4);--color-text-inverted: var(--white);--color-code-comment: var(--green);--color-input: var(--color-background);--color-input-text: var(--color-text);--color-button: var(--turq-dark);--color-button-disabled: var(--gray-9);--color-button-text: var(--white);--color-button-text-disabled: var(--gray-3);--color-button-inverted: var(--color-background);--color-button-inverted-disabled: var(--color-background);--color-button-inverted-text: var(--color-brand-primary);--color-button-inverted-text-disabled: var(--color-text-subtle);--color-button-accented: var(--yellow);--color-button-accented-disabled: var(--gray-9);--color-button-accented-text: var(--gray-1);--color-button-accented-text-disabled: var(--gray-3)}[data-theme=dark]{--color-brand-primary: var(--turq-med);--color-background: var(--gray-1);--color-background-accented: var(--gray-2);--color-background-highlighted: var(--gray-2);--color-background-highlighted-link: var(--gray-2);--color-background-info: var(--gray-3);--color-background-warning: var(--yellow);--color-background-alert: var(--pink);--color-border: var(--gray-4);--color-text: var(--gray-9);--color-text-subtle: var(--gray-7);--color-code-comment: var(--green-light)}@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){--color-brand-primary: var(--turq-med);--color-background: var(--gray-1);--color-background-accented: var(--gray-2);--color-background-highlighted: var(--gray-2);--color-background-highlighted-link: var(--gray-2);--color-background-info: var(--gray-3);--color-background-warning: var(--yellow);--color-background-alert: var(--pink);--color-border: var(--gray-4);--color-text: var(--gray-9);--color-text-subtle: var(--gray-7);--color-code-comment: var(--green-light)}}.go-Footer{background-color:var(--color-background-inverted);color:var(--color-text-inverted);font-size:.875rem;width:100%}.go-Footer-links{display:flex;flex-wrap:wrap;justify-content:space-between;margin:auto;max-width:75.75rem;padding:2rem 1.5rem 2.625rem}.go-Footer-linkColumn{flex:0 0 9.5rem}.go-Footer .go-Footer-link{color:var(--color-text-inverted);display:flex;flex:1;font-size:.875rem;line-height:2rem}.go-Footer .go-Footer-link--primary{font-size:1.125rem;line-height:1.75rem;margin-bottom:.5rem;margin-top:.75rem}.go-Footer-bottom{align-items:center;border-top:var(--border);display:flex;margin:0 1.5rem;min-height:4.125rem}.go-Footer-gopher{align-self:flex-end;height:3.147rem;width:5rem}.go-Footer-listRow{display:flex;flex:1;flex-wrap:wrap;list-style:none;margin:0;padding:0;text-align:center}.go-Footer-listItem{align-items:center;display:flex;flex:1 100%;justify-content:center;margin:.4rem 0;padding:0 1rem}.go-Footer-listItem a:link,.go-Footer-listItem a:visited{color:var(--color-text-inverted)}.go-Footer-googleLogo{align-self:flex-end;height:1.5rem;margin-bottom:1.3rem;text-align:right}.go-Footer-googleLogoImg{height:1.5rem;width:4.529rem}@media only screen and (min-width: 52rem){.go-Footer-listItem{flex:initial}.go-Footer-listItem+.go-Footer-listItem{border-left:var(--border)}}select:focus:not([disabled]),input:focus:not([disabled]){border-color:var(--color-brand-primary);-webkit-box-shadow:var(--focus-box-shadow);box-shadow:var(--focus-box-shadow);outline:transparent;z-index:2}input::placeholder{color:var(--color-text-subtle)}.go-Form{align-items:start;display:flex;flex-direction:column;gap:1rem}.go-Label{display:flex;flex-direction:column;gap:.5rem}.go-Label--inline{align-items:center;flex-direction:row}.go-Label legend{margin-bottom:.5rem}.go-Label--inline legend{float:left;margin-bottom:0}.go-Input,.go-Select{background:var(--color-input);border:var(--border);border-radius:var(--border-radius);color:var(--color-input-text)}.go-Input{padding:.40625rem .5rem}.go-Select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:url(/static/shared/icon/arrow_drop_down_gm_grey_24dp.svg) right no-repeat;background-color:var(--color-background);background-position:right center;border-radius:var(--border-radius);margin:0;padding:.34375rem 1.25rem .34375rem .5rem}.go-InputGroup{display:flex}.go-InputGroup .go-Input{flex:1}.go-InputGroup>:not(:first-child,:last-child){border-radius:0;margin-left:-.0625rem}.go-InputGroup>:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.go-InputGroup>:last-child{border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-.0625rem}.go-InputGroup>*:hover,.go-InputGroup>*:focus{z-index:1}.go-ShortcutKey{display:flex;position:relative}.go-ShortcutKey .go-Input{flex-grow:1}.go-ShortcutKey:after{align-self:center;background-color:var(--color-background-accented);border-radius:.5rem;color:var(--gray-6);content:attr(data-shortcut);content:attr(data-shortcut) / attr(data-shortcut-alt);display:none;font-size:.75rem;padding:.0625rem 0;position:absolute;right:.75rem;text-align:center;width:1.5rem;z-index:1}@media only screen and (min-width: 52rem){.go-ShortcutKey:after{display:initial}}.go-GopherMessage img{display:block;height:15rem;margin:0 auto;padding:1.25rem 0;width:15rem}.go-GopherMessage p{font-weight:600;margin:auto;text-align:center}.go-Banner{background-color:var(--gray-1);display:none}.go-Banner-inner{align-items:center;display:flex;justify-content:space-between;margin:0 auto;max-width:75.75rem;min-height:2.5rem;padding:.5rem var(--gutter)}.Site--wide .go-Banner-inner{max-width:98rem}.go-Banner--full .go-Banner-inner{max-width:unset}.go-Banner-message{color:var(--white);margin-right:1.25rem}.go-Banner-action:link,.go-Banner-action:visited{color:var(--white);text-decoration:underline;white-space:nowrap}@media only screen and (min-width: 52rem){.go-Banner{display:block}}.go-Header{background:#007d9c;border-bottom:none;box-shadow:0 .0625rem .125rem #ababab4d;top:0;width:100%;z-index:10}.go-Header-inner{margin:0 auto;max-width:75.75rem;padding:0 var(--gutter)}.Site--wide .go-Header-inner{max-width:98rem}.go-Header--full .go-Header-inner{max-width:initial}.go-Header-nav{align-items:center;display:flex;height:3.5rem;justify-content:space-between}.go-Header-rightContent{align-items:center;display:flex;height:100%;justify-content:flex-end;width:100%}.go-Header-rightContent form{flex-grow:1}.go-Header-inner--dark{border-bottom:none;color:var(--white)}.go-Header-logo{display:block;height:2rem;margin-right:2.25rem;width:5.125rem}.go-Header-logo--hidden{display:none}.go-Header-menuItem{display:none}.go-Header-menu{align-items:stretch;display:flex;height:100%;list-style:none;margin:0;padding:0}@media only screen and (min-width: 65rem){.go-Header-menuItem{align-items:stretch;display:inline-flex;flex:none}.go-Header-menu{justify-content:flex-end}.go-Header-navOpen{display:none}}.go-Header-menuItem a:link,.go-Header-menuItem a:visited{align-items:center;border-bottom:.1875rem solid transparent;border-top:.1875rem solid transparent;color:var(--gray-2);display:inline-flex;margin:0 .3125rem;padding:0 .9375rem;text-align:center;text-decoration:none;width:100%}.go-Header-menuItem--active a:link,.go-Header-menuItem--active a:visited{border-bottom-color:var(--turq-med);font-weight:bold}.go-Header-menuItem a:hover{border-bottom-color:var(--white);color:var(--gray-2)}.go-NavigationDrawer-listItem a:link,.go-NavigationDrawer-listItem a:visited{display:block;margin:0 1rem;padding:.5rem}.go-Header-inner--dark .go-Header-menuItem a:link,.go-Header-inner--dark .go-Header-menuItem a:visited{color:var(--white)}.go-Header-navOpen{background:no-repeat center/2rem url(/images/menu-24px.svg);border:none;height:2.5rem;margin-left:1rem;width:2.5rem}.go-Header-navOpen--hidden{display:none}.go-Header-navOpen--white{background:no-repeat center/2rem url(/static/shared/icon/menu_gm_grey_24dp.svg);filter:brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg) brightness(103%) contrast(107%)}.go-SearchForm--expanded{flex-grow:1}.go-SearchForm-form{display:none}.go-SearchForm-form:after{right:2.75rem}.go-SearchForm--expanded .go-SearchForm-form{display:flex}.go-SearchForm-expandSearch{appearance:none;background:none;font-size:1.5rem}.go-SearchForm--expanded .go-SearchForm-expandSearch{display:none}@media only screen and (min-width: 32rem){.go-Header-rightContent{width:100%}.go-SearchForm{flex:1}.go-SearchForm-form{display:flex}.go-SearchForm-expandSearch{display:none}.go-Header-logo--hidden{display:initial}}.go-NavigationDrawer{background:var(--white);height:100%;left:auto;max-width:27rem;position:fixed;right:0;top:0;transform:translate(100%);transition:transform .1s ease-in-out;width:85%;z-index:30}@media only screen and (min-width: 65rem){.go-NavigationDrawer{display:none}}.go-NavigationDrawer.is-active{transform:translate(0)}.go-NavigationDrawer-header{align-items:center;display:flex;justify-content:space-between}.go-NavigationDrawer-logo{display:block;height:2rem;margin:1rem;width:5.125rem}.go-NavigationDrawer-list{list-style:none;margin:0;padding:0}.go-NavigationDrawer-listItem{font-size:1.125rem;margin:0 .5rem}.go-NavigationDrawer-listItem--active{background-color:var(--blue);border-radius:.4rem}.go-NavigationDrawer-scrim{display:none;height:100%;left:0;position:fixed;top:0;width:100%;z-index:20}.go-NavigationDrawer.is-active+.go-NavigationDrawer-scrim{background-color:var(--gray-1);display:block;opacity:.32}.go-Icon{filter:none;height:1.125em;vertical-align:text-bottom;width:auto}.go-Icon--accented{filter:brightness(0) invert(45%) sepia(94%) saturate(6735%) hue-rotate(176deg) brightness(94%) contrast(101%)}.go-Icon--inverted{filter:brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg) brightness(103%) contrast(107%)}[data-theme=dark] .go-Icon:not(.go-Icon--accented){filter:brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg) brightness(103%) contrast(107%)}[data-theme=dark] .go-Icon--accented{filter:brightness(0) invert(69%) sepia(46%) saturate(466%) hue-rotate(153deg) brightness(90%) contrast(88%)}@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .go-Icon:not(.go-Icon--accented){filter:brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg) brightness(103%) contrast(107%)}:root:not([data-theme="light"]) .go-Icon--accented{filter:brightness(0) invert(57%) sepia(63%) saturate(4864%) hue-rotate(160deg) brightness(100%) contrast(101%)}}.go-Message{color:var(--color-text);font-size:.875rem;line-height:1.5rem;padding:0 var(--gutter);width:100%}.go-Message--notice{background-color:var(--color-background-info)}.go-Message--warning{background-color:var(--color-background-warning);color:var(--gray-1)}.go-Message--alert{background-color:var(--color-background-alert)}.go-Message>.go-Icon{vertical-align:text-top}[data-theme=dark] .go-Message--warning .go-Icon{filter:none}@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .go-Message--warning .go-Icon{filter:none}}dialog{position:absolute;left:0;right:0;width:-moz-fit-content;width:-webkit-fit-content;width:fit-content;height:-moz-fit-content;height:-webkit-fit-content;height:fit-content;margin:auto;border:solid;padding:1em;background:white;color:#000;display:block}dialog:not([open]){display:none}dialog+.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.1)}._dialog_overlay{position:fixed;top:0;right:0;bottom:0;left:0}dialog.fixed{position:fixed;top:50%;transform:translateY(-50%)}.go-Modal{background:var(--color-background);border:var(--border);border-radius:var(--border-radius);bottom:0;box-shadow:var(--box-shadow);color:var(--color-text);display:flex;flex-direction:column;gap:1rem;max-height:100%;max-width:100%;position:fixed;top:0}.go-Modal>form{display:contents}.go-Modal--small{width:20rem}.go-Modal--md{width:30rem}.go-Modal--lg{width:40rem}.go-Modal-header{display:flex;justify-content:space-between}.go-Modal-header h2{font-size:1.15rem;line-height:1.25rem}.go-Modal-body{flex-grow:1;min-height:2rem;min-width:18rem}.go-Modal-actions{text-align:right}@media not all and (min-resolution: .001dpcm){@supports (-webkit-appearance: none){.go-Modal{padding-bottom:0}}}.go-Tree{--js-tree-height: 0;display:flex;flex-direction:column}.go-Tree ul{list-style:none;padding-left:0}.go-Tree li:last-of-type{padding-bottom:.25rem}.go-Tree a+ul{display:none}.go-Tree a[aria-expanded=true]+ul[role=group]{display:block}.go-Tree a[aria-level="1"]+ul[role=group]{max-height:calc(100vh - var(--js-tree-height, 0) - var(--js-sticky-header-height, 3.5rem) - 5rem);overflow-y:auto;padding:.5rem .25rem 0}.go-Tree a{color:var(--color-text-subtle);display:block;line-height:1.5rem;overflow:hidden;padding:.125rem 0 .125rem 1.25rem;position:relative;text-overflow:ellipsis;user-select:none;white-space:nowrap}.go-Tree>li>a,.go-Tree a[aria-level="1"]{display:block;font-size:1rem;font-weight:500;line-height:2.5rem;padding:0 1rem}.go-Tree a:focus,.go-Tree a:hover{text-decoration:underline;z-index:1}.go-Tree a[aria-selected=true]{color:var(--color-text);font-weight:500}.go-Tree a[aria-level="1"][aria-selected=true],.go-Tree a[aria-level="1"][aria-expanded=true]{background-color:var(--color-background-accented)}.go-Tree a[aria-level="3"][aria-expanded=true]{margin-bottom:.375em}.go-Tree a[aria-level="2"]{margin-bottom:.25rem;position:relative}.go-Tree a[aria-level="3"]{padding-left:2.5rem}.go-Tree a[aria-level="4"]{border-left:.125rem solid var(--color-background-accented);margin-left:2.5rem;padding-left:.5rem}.go-Tree a[aria-selected=true][aria-level="2"]:not([aria-expanded]):before,.go-Tree a[aria-selected=true][aria-level="3"]:not([aria-expanded]):before{background-color:var(--color-brand-primary);border-radius:50%;content:"";display:block;height:.3125rem;left:.4688rem;position:absolute;top:.75rem;width:.3125rem}.go-Tree a[aria-expanded][aria-owns][aria-level="2"]:before,.go-Tree a[aria-expanded][aria-owns][aria-level="3"]:before{border-bottom:.25rem solid transparent;border-left:.25rem solid var(--color-border);border-right:0;border-top:.25rem solid transparent;content:"";display:block;height:0;left:.5rem;position:absolute;top:.625rem;transition:transform .1s linear;width:0}.go-Tree a[aria-expanded=true][aria-level="2"]:before,.go-Tree a[aria-expanded=true][aria-level="3"]:before{transform:rotate(90deg)}.go-Tree a[aria-expanded][aria-level="3"]:not([empty]):before,.go-Tree a[aria-selected][aria-level="3"]:not([empty]):before{left:1.5rem;top:.75rem}.go-Tree a[aria-selected=true][aria-level="4"]{border-left:.125rem solid var(--color-brand-primary)}.go-TabNav{margin:0 0 .5rem}.go-TabNav ul{display:flex;gap:2rem}.go-TabNav li{border-bottom:.25rem transparent solid;display:flex;font-size:1rem;height:2.375rem;padding:0 .25rem}.go-TabNav li[aria-current]{border-color:var(--color-brand-primary)}.go-TabNav li:hover{border-color:var(--color-brand-primary)}.go-TabNav a{align-items:center;color:var(--color-text-subtle);display:inline-flex}.go-TabNav li:hover a{text-decoration:none}.go-TabNav li[aria-current] a{color:var(--color-text)}.go-Tooltip{border-radius:var(--border-radius);cursor:pointer;display:inline-block;position:relative}.go-Tooltip>summary{list-style:none}.go-Tooltip>summary::-webkit-details-marker,.go-Tooltip>summary::marker{display:none}.go-Tooltip>summary>img{vertical-align:text-bottom}.go-Tooltip p{background:var(--color-background) 80%;border:var(--border);border-radius:var(--border-radius);color:var(--color-text);font-size:.75rem;letter-spacing:.01875rem;line-height:1rem;padding:.5rem;position:absolute;top:1.5rem;white-space:normal;width:12rem;z-index:100}:root{--gutter: 1rem;--gap: 1rem;--scroll-margin: calc( var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 2rem );--border: .0625rem solid var(--color-border);--border-radius: .25rem;--box-shadow: 0 0 .375rem 0 rgb(0 0 0 / 25%);--focus-box-shadow: 0 0 .0625rem .0625rem rgba(0, 112, 210, .6)}[data-theme=dark]{--box-shadow: 0 .3125rem .9375rem rgb(0 0 0 / 45%)}@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){--box-shadow: 0 .3125rem .9375rem rgb(0 0 0 / 45%)}}@media (min-width: 50rem){:root{--gutter: 1.5rem;--gap: 2rem;--scroll-margin: calc( var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 1rem )}}@media (min-width: 80rem){:root{--gutter: 2rem}}@media (min-width: 112rem){:root{--gutter: 2.5rem}}*:target{scroll-margin-top:var(--scroll-margin)}body{background-color:var(--color-background);display:flex;flex-direction:column;min-height:100vh;min-width:23.5rem;-webkit-overflow-scrolling:touch}.go-Container{display:flex;flex-direction:column;flex-grow:1;height:100%;margin-bottom:5rem}.go-Content{display:flex;flex-flow:column;gap:1rem;margin:0 auto;max-width:63rem;min-height:32rem;padding:2rem var(--gutter);width:100%}.go-Content--center{justify-content:center;margin:auto}
+html,body,button,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,hr,input,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,dialog,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font:inherit;font-size:100%;margin:0;padding:0;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:"";content:none}table{border-collapse:collapse;border-spacing:0}*,:before,:after{box-sizing:border-box}body{color:var(--color-text);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";font-size:1rem;line-height:normal}h1{font-size:1.5rem}h2{font-size:1.375rem}h3{font-size:1.25rem}h4{font-size:1.125rem}h5{font-size:1rem}h6{font-size:.875rem}h1,h2,h3,h4{font-weight:600;line-height:1.25em;word-break:break-word}h5,h6{font-weight:500;line-height:1.3em;word-break:break-word}hr{border:none;border-bottom:var(--border);margin:0;width:100%}p{font-size:1rem;line-height:1.5rem;max-width:60rem}strong{font-weight:600}.go-textSubtle{color:var(--color-text-subtle)}.go-textTitle{font-size:1.125rem;font-weight:600;line-height:1.25rem}.go-textLabel{font-size:.875rem;font-weight:600;line-height:1rem}.go-textPagination{font-size:.875rem;line-height:1rem}code,pre,textarea.code{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:.875rem;line-height:1.5em}pre,textarea.code{background-color:var(--color-background-accented);border:var(--border);border-radius:var(--border-radius);color:var(--color-text);overflow-x:auto;padding:.625rem;tab-size:4;white-space:pre}button,input,select,textarea{font:inherit}a,a:link,a:visited{color:var(--color-brand-primary);text-decoration:none}a:hover,a:hover>*{color:var(--color-brand-primary);text-decoration:underline}button:focus:not([disabled]){border-color:var(--color-brand-primary);-webkit-box-shadow:var(--focus-box-shadow);box-shadow:var(--focus-box-shadow);outline:transparent}.go-Button{align-items:center;background-color:var(--color-button);border:.0625rem solid transparent;border-radius:var(--border-radius);color:var(--color-button-text);cursor:pointer;display:inline-flex;font-weight:500;gap:.25rem}.go-Button:not(.go-Button--inline){padding:.5rem}.go-Button--accented{background-color:var(--color-button-accented);color:var(--color-button-accented-text)}.go-Button--inverted,.go-Button--text,.go-Button--inline{background-color:var(--color-button-inverted);color:var(--color-button-inverted-text)}.go-Button--inline{background-color:transparent}.go-Button--inverted{border:var(--border)}.go-Button:hover{box-shadow:var(--focus-box-shadow);filter:contrast(.95)}.go-Button--inline:hover{box-shadow:none;text-decoration:underline var(--color-button-inverted-text)}.go-Button:focus{filter:contrast(.95)}.go-Button--inverted:focus{border-color:var(--color-button-inverted-text)}.go-Button:active{box-shadow:none;filter:contrast(.85)}.go-Button:disabled{background-color:var(--color-button-disabled);box-shadow:none;color:var(--color-button-text-disabled);cursor:initial;filter:none;text-decoration:none}.go-Button--accented:disabled{background-color:var(--color-button-accented-disabled);color:var(--color-button-accented-text-disabled)}.go-Button--inverted:disabled,.go-Button--text:disabled,.go-Button--inline:disabled{background-color:var(--color-button-inverted-disabled);color:var(--color-button-inverted-text-disabled)}.go-Button--inline:disabled{background-color:transparent}.go-Breadcrumb ol{line-height:1.5rem;white-space:initial}.go-Breadcrumb li{align-items:center;color:var(--color-text-subtle);display:inline-flex;font-size:.875rem}.go-Breadcrumb li:not(:last-child):after{content:">";padding:0 .5rem}.go-Breadcrumb li:last-child>a{color:var(--color-text-subtle)}.go-Breadcrumb li>.go-Clipboard{margin:0 .5rem}.go-Carousel{align-items:center;display:flex;flex-direction:column;position:relative;text-align:center}.go-Carousel-slide{margin:.5rem 3rem}.go-Carousel-slide[aria-hidden]{display:none}.go-Carousel-prevSlide{left:0}.go-Carousel-nextSlide{right:0}.go-Carousel-prevSlide,.go-Carousel-nextSlide{background-color:transparent;border-radius:var(--border-radius);font-size:1.5rem;height:2.75rem;margin-top:-1.375rem;opacity:0;position:absolute;top:50%;width:2.75rem}.go-Carousel-prevSlide:hover,.go-Carousel-nextSlide:hover{background-color:var(--color-background-accented);cursor:pointer}.go-Carousel:hover .go-Carousel-prevSlide,.go-Carousel:hover .go-Carousel-nextSlide,.go-Carousel:focus-within .go-Carousel-prevSlide,.go-Carousel:focus-within .go-Carousel-nextSlide{opacity:1}.go-Carousel-dots{display:flex;font-size:.4375rem;gap:.5rem}.go-Carousel-dot{background-color:var(--color-border);border-radius:2rem;height:.4375rem;width:.4375rem}.go-Carousel-dot--active,.go-Carousel-dot:hover{background-color:var(--color-text-subtle)}.go-Carousel-obscured{border:0;clip:rect(0 0 0 0);height:.0625rem;margin:-.0625rem;overflow:hidden;padding:0;position:absolute;width:.0625rem}.go-Chip{background:var(--color-button);border:.0625rem solid var(--color-button);border-radius:1.25rem;color:var(--color-button-text);font-size:.75rem;padding:.125rem .625rem}.go-Chip--accented{background:var(--color-button-accented);border:.0625rem solid var(--color-button-accented);color:var(--color-button-accented-text)}.go-Chip--inverted{background:var(--color-button-inverted);border:var(--border);color:var(--color-text)}.go-Chip--highlighted{background:var(--color-background-highlighted-link);border-color:var(--color-background-highlighted-link);color:var(--color-brand-primary)}.go-Chip--alert{background:var(--pink);border:.0625rem solid var(--pink);color:var(--color-text-inverted)}.go-Chip--vuln{background:var(--pink-light);border:.0625rem solid var(--pink-light);color:var(--color-text-inverted)}.go-Chip--subtle{background-color:var(--color-background-accented);border-color:transparent;color:var(--color-text-subtle)}.go-Clipboard{position:relative}.go-Clipboard:before{background-color:var(--color-background-inverted);border-radius:var(--border-radius);color:var(--color-text-inverted);content:attr(data-tooltip);display:block;font-size:.9em;left:calc(100% + .125rem);padding:.25rem .3rem;position:absolute;text-transform:uppercase;top:.125rem;white-space:nowrap;z-index:1000}.go-Clipboard:after{border-bottom:.25rem solid transparent;border-left:0;border-right:.25rem solid var(--color-background-inverted);border-top:.25rem solid transparent;content:"";display:block;position:absolute;right:-.125rem;top:.5625rem;z-index:1000}.go-Clipboard:not([data-tooltip]):before,.go-Clipboard:not([data-tooltip]):after,.go-Clipboard[data-tooltip=""]:before,.go-Clipboard[data-tooltip=""]:after{display:none}:root{--gray-1: #202224;--gray-2: #3e4042;--gray-3: #555759;--gray-4: #6e7072;--gray-5: #848688;--gray-6: #aaacae;--gray-7: #c6c8ca;--gray-8: #dcdee0;--gray-9: #f0f1f2;--gray-10: #f8f8f8;--turq-light: #5dc9e2;--turq-med: #50b7e0;--turq-dark: #007d9c;--blue: #bfeaf4;--blue-light: #f2fafd;--black: #000;--green: #3a6e11;--green-light: #5fda64;--pink: #ce3262;--pink-light: #fdecf1;--purple: #542c7d;--slate: #253443;--white: #fff;--yellow: #fddd00;--yellow-light: #fff8cc;--color-brand-primary: var(--turq-dark);--color-background: var(--white);--color-background-inverted: var(--slate);--color-background-accented: var(--gray-10);--color-background-highlighted: var(--blue);--color-background-highlighted-link: var(--blue-light);--color-background-info: var(--gray-9);--color-background-warning: var(--yellow-light);--color-background-alert: var(--pink-light);--color-border: var(--gray-7);--color-text: var(--gray-1);--color-text-subtle: var(--gray-4);--color-text-inverted: var(--white);--color-code-comment: var(--green);--color-input: var(--color-background);--color-input-text: var(--color-text);--color-button: var(--turq-dark);--color-button-disabled: var(--gray-9);--color-button-text: var(--white);--color-button-text-disabled: var(--gray-3);--color-button-inverted: var(--color-background);--color-button-inverted-disabled: var(--color-background);--color-button-inverted-text: var(--color-brand-primary);--color-button-inverted-text-disabled: var(--color-text-subtle);--color-button-accented: var(--yellow);--color-button-accented-disabled: var(--gray-9);--color-button-accented-text: var(--gray-1);--color-button-accented-text-disabled: var(--gray-3)}[data-theme=dark]{--color-brand-primary: var(--turq-med);--color-background: var(--gray-1);--color-background-accented: var(--gray-2);--color-background-highlighted: var(--gray-2);--color-background-highlighted-link: var(--gray-2);--color-background-info: var(--gray-3);--color-background-warning: var(--yellow);--color-background-alert: var(--pink);--color-border: var(--gray-4);--color-text: var(--gray-9);--color-text-subtle: var(--gray-7);--color-code-comment: var(--green-light)}@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){--color-brand-primary: var(--turq-med);--color-background: var(--gray-1);--color-background-accented: var(--gray-2);--color-background-highlighted: var(--gray-2);--color-background-highlighted-link: var(--gray-2);--color-background-info: var(--gray-3);--color-background-warning: var(--yellow);--color-background-alert: var(--pink);--color-border: var(--gray-4);--color-text: var(--gray-9);--color-text-subtle: var(--gray-7);--color-code-comment: var(--green-light)}}.go-Footer{background-color:var(--color-background-inverted);color:var(--color-text-inverted);font-size:.875rem;width:100%}.go-Footer-links{display:flex;flex-wrap:wrap;justify-content:space-between;margin:auto;max-width:75.75rem;padding:2rem 1.5rem 2.625rem}.go-Footer-linkColumn{flex:0 0 9.5rem}.go-Footer .go-Footer-link{color:var(--color-text-inverted);display:flex;flex:1;font-size:.875rem;line-height:2rem}.go-Footer .go-Footer-link--primary{font-size:1.125rem;line-height:1.75rem;margin-bottom:.5rem;margin-top:.75rem}.go-Footer-bottom{align-items:center;border-top:var(--border);display:flex;margin:0 1.5rem;min-height:4.125rem}.go-Footer-gopher{align-self:flex-end;height:3.147rem;width:5rem}.go-Footer-listRow{display:flex;flex:1;flex-wrap:wrap;list-style:none;margin:0;padding:0;text-align:center}.go-Footer-listItem{align-items:center;display:flex;flex:1 100%;justify-content:center;margin:.4rem 0;padding:0 1rem}.go-Footer-listItem a:link,.go-Footer-listItem a:visited{color:var(--color-text-inverted)}.go-Footer-listItem .go-Button--text{background-color:transparent;font-size:1rem}.go-Footer-listItem [data-value]{display:none}[data-theme=auto] .go-Footer-listItem [data-value=auto],:root:not([data-theme]) .go-Footer-listItem [data-value=auto]{display:initial}[data-theme=dark] .go-Footer-listItem [data-value=dark]{display:initial}[data-theme=light] .go-Footer-listItem [data-value=light]{display:initial}.go-Footer-toggleTheme,.go-Footer-keyboard{margin:0 0 .5rem}.go-Footer-googleLogo{align-self:flex-end;height:1.5rem;margin-bottom:1.3rem;text-align:right}.go-Footer-googleLogoImg{height:1.5rem;width:4.529rem}@media only screen and (min-width: 52rem){.go-Footer-listItem{flex:initial}.go-Footer-listItem+.go-Footer-listItem{border-left:var(--border)}.go-Footer-toggleTheme{margin:0 0 0 -.5rem}.go-Footer-keyboard{margin:0}}select:focus:not([disabled]),input:focus:not([disabled]){border-color:var(--color-brand-primary);-webkit-box-shadow:var(--focus-box-shadow);box-shadow:var(--focus-box-shadow);outline:transparent;z-index:2}input::placeholder{color:var(--color-text-subtle)}.go-Form{align-items:start;display:flex;flex-direction:column;gap:1rem}.go-Label{display:flex;flex-direction:column;gap:.5rem}.go-Label--inline{align-items:center;flex-direction:row}.go-Label legend{margin-bottom:.5rem}.go-Label--inline legend{float:left;margin-bottom:0}.go-Input,.go-Select{background:var(--color-input);border:var(--border);border-radius:var(--border-radius);color:var(--color-input-text)}.go-Input{padding:.40625rem .5rem}.go-Select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:url(/static/shared/icon/arrow_drop_down_gm_grey_24dp.svg) right no-repeat;background-color:var(--color-background);background-position:right center;border-radius:var(--border-radius);margin:0;padding:.34375rem 1.25rem .34375rem .5rem}.go-InputGroup{display:flex}.go-InputGroup .go-Input{flex:1}.go-InputGroup>:not(:first-child,:last-child){border-radius:0;margin-left:-.0625rem}.go-InputGroup>:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.go-InputGroup>:last-child{border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-.0625rem}.go-InputGroup>*:hover,.go-InputGroup>*:focus{z-index:1}.go-ShortcutKey{display:flex;position:relative}.go-ShortcutKey .go-Input{flex-grow:1}.go-ShortcutKey:after{align-self:center;background-color:var(--color-background-accented);border-radius:.5rem;color:var(--gray-6);content:attr(data-shortcut);content:attr(data-shortcut) / attr(data-shortcut-alt);display:none;font-size:.75rem;padding:.0625rem 0;position:absolute;right:.75rem;text-align:center;width:1.5rem;z-index:1}@media only screen and (min-width: 52rem){.go-ShortcutKey:after{display:initial}}.go-GopherMessage img{display:block;height:15rem;margin:0 auto;padding:1.25rem 0;width:15rem}.go-GopherMessage p{font-weight:600;margin:auto;text-align:center}.go-Banner{background-color:var(--gray-1);display:none}.go-Banner-inner{align-items:center;display:flex;justify-content:space-between;margin:0 auto;max-width:75.75rem;min-height:2.5rem;padding:.5rem var(--gutter)}.Site--wide .go-Banner-inner{max-width:98rem}.go-Banner--full .go-Banner-inner{max-width:unset}.go-Banner-message{color:var(--white);margin-right:1.25rem}.go-Banner-action:link,.go-Banner-action:visited{color:var(--white);text-decoration:underline;white-space:nowrap}@media only screen and (min-width: 52rem){.go-Banner{display:block}}.go-Header{background:#007d9c;border-bottom:none;box-shadow:0 .0625rem .125rem #ababab4d;top:0;width:100%;z-index:10}.go-Header-inner{margin:0 auto;max-width:75.75rem;padding:0 var(--gutter)}.Site--wide .go-Header-inner{max-width:98rem}.go-Header--full .go-Header-inner{max-width:initial}.go-Header-nav{align-items:center;display:flex;height:3.5rem;justify-content:space-between}.go-Header-rightContent{align-items:center;display:flex;height:100%;justify-content:flex-end;width:100%}.go-Header-rightContent form{flex-grow:1}.go-Header-inner--dark{border-bottom:none;color:var(--white)}.go-Header-logo{display:block;height:2rem;margin-right:2.25rem;width:5.125rem}.go-Header-logo--hidden{display:none}.go-Header-menuItem{display:none}.go-Header-menu{align-items:stretch;display:flex;height:100%;list-style:none;margin:0;padding:0}@media only screen and (min-width: 65rem){.go-Header-menuItem{align-items:stretch;display:inline-flex;flex:none}.go-Header-menu{justify-content:flex-end}.go-Header-navOpen{display:none}}.go-Header-menuItem a:link,.go-Header-menuItem a:visited{align-items:center;border-bottom:.1875rem solid transparent;border-top:.1875rem solid transparent;color:var(--gray-2);display:inline-flex;margin:0 .3125rem;padding:0 .9375rem;text-align:center;text-decoration:none;width:100%}.go-Header-menuItem--active a:link,.go-Header-menuItem--active a:visited{border-bottom-color:var(--turq-med);font-weight:bold}.go-Header-menuItem a:hover{border-bottom-color:var(--white);color:var(--gray-2)}.go-NavigationDrawer-listItem a:link,.go-NavigationDrawer-listItem a:visited{display:block;margin:0 1rem;padding:.5rem}.go-Header-inner--dark .go-Header-menuItem a:link,.go-Header-inner--dark .go-Header-menuItem a:visited{color:var(--white)}.go-Header-navOpen{background:no-repeat center/2rem url(/images/menu-24px.svg);border:none;height:2.5rem;margin-left:1rem;width:2.5rem}.go-Header-navOpen--hidden{display:none}.go-Header-navOpen--white{background:no-repeat center/2rem url(/static/shared/icon/menu_gm_grey_24dp.svg);filter:brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg) brightness(103%) contrast(107%)}.go-SearchForm--expanded{flex-grow:1}.go-SearchForm-form{display:none}.go-SearchForm-form:after{right:2.75rem}.go-SearchForm--expanded .go-SearchForm-form{display:flex}.go-SearchForm-expandSearch{appearance:none;background:none;font-size:1.5rem}.go-SearchForm--expanded .go-SearchForm-expandSearch{display:none}@media only screen and (min-width: 32rem){.go-Header-rightContent{width:100%}.go-SearchForm{flex:1}.go-SearchForm-form{display:flex}.go-SearchForm-expandSearch{display:none}.go-Header-logo--hidden{display:initial}}.go-NavigationDrawer{background:var(--white);height:100%;left:auto;max-width:27rem;position:fixed;right:0;top:0;transform:translate(100%);transition:transform .1s ease-in-out;width:85%;z-index:30}@media only screen and (min-width: 65rem){.go-NavigationDrawer{display:none}}.go-NavigationDrawer.is-active{transform:translate(0)}.go-NavigationDrawer-header{align-items:center;display:flex;justify-content:space-between}.go-NavigationDrawer-logo{display:block;height:2rem;margin:1rem;width:5.125rem}.go-NavigationDrawer-list{list-style:none;margin:0;padding:0}.go-NavigationDrawer-listItem{font-size:1.125rem;margin:0 .5rem}.go-NavigationDrawer-listItem--active{background-color:var(--blue);border-radius:.4rem}.go-NavigationDrawer-scrim{display:none;height:100%;left:0;position:fixed;top:0;width:100%;z-index:20}.go-NavigationDrawer.is-active+.go-NavigationDrawer-scrim{background-color:var(--gray-1);display:block;opacity:.32}.go-Icon{filter:none;height:1.125em;vertical-align:text-bottom;width:auto}.go-Icon--accented{filter:brightness(0) invert(45%) sepia(94%) saturate(6735%) hue-rotate(176deg) brightness(94%) contrast(101%)}.go-Icon--inverted{filter:brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg) brightness(103%) contrast(107%)}[data-theme=dark] .go-Icon:not(.go-Icon--accented){filter:brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg) brightness(103%) contrast(107%)}[data-theme=dark] .go-Icon--accented{filter:brightness(0) invert(69%) sepia(46%) saturate(466%) hue-rotate(153deg) brightness(90%) contrast(88%)}@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .go-Icon:not(.go-Icon--accented){filter:brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg) brightness(103%) contrast(107%)}:root:not([data-theme="light"]) .go-Icon--accented{filter:brightness(0) invert(57%) sepia(63%) saturate(4864%) hue-rotate(160deg) brightness(100%) contrast(101%)}}.go-Message{color:var(--color-text);font-size:.875rem;line-height:1.5rem;padding:0 var(--gutter);width:100%}.go-Message--notice{background-color:var(--color-background-info)}.go-Message--warning{background-color:var(--color-background-warning);color:var(--gray-1)}.go-Message--alert{background-color:var(--color-background-alert)}.go-Message>.go-Icon{vertical-align:text-top}[data-theme=dark] .go-Message--warning .go-Icon{filter:none}@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .go-Message--warning .go-Icon{filter:none}}dialog{position:absolute;left:0;right:0;width:-moz-fit-content;width:-webkit-fit-content;width:fit-content;height:-moz-fit-content;height:-webkit-fit-content;height:fit-content;margin:auto;border:solid;padding:1em;background:white;color:#000;display:block}dialog:not([open]){display:none}dialog+.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.1)}._dialog_overlay{position:fixed;top:0;right:0;bottom:0;left:0}dialog.fixed{position:fixed;top:50%;transform:translateY(-50%)}.go-Modal{background:var(--color-background);border:var(--border);border-radius:var(--border-radius);bottom:0;box-shadow:var(--box-shadow);color:var(--color-text);display:flex;flex-direction:column;gap:1rem;max-height:100%;max-width:100%;position:fixed;top:0}.go-Modal>form{display:contents}.go-Modal--small{width:20rem}.go-Modal--md{width:30rem}.go-Modal--lg{width:40rem}.go-Modal-header{display:flex;justify-content:space-between}.go-Modal-header h2{font-size:1.15rem;line-height:1.25rem}.go-Modal-body{flex-grow:1;min-height:2rem;min-width:18rem}.go-Modal-actions{text-align:right}@media not all and (min-resolution: .001dpcm){@supports (-webkit-appearance: none){.go-Modal{padding-bottom:0}}}.go-Tree{--js-tree-height: 0;display:flex;flex-direction:column}.go-Tree ul{list-style:none;padding-left:0}.go-Tree li:last-of-type{padding-bottom:.25rem}.go-Tree a+ul{display:none}.go-Tree a[aria-expanded=true]+ul[role=group]{display:block}.go-Tree a[aria-level="1"]+ul[role=group]{max-height:calc(100vh - var(--js-tree-height, 0) - var(--js-sticky-header-height, 3.5rem) - 5rem);overflow-y:auto;padding:.5rem .25rem 0}.go-Tree a{color:var(--color-text-subtle);display:block;line-height:1.5rem;overflow:hidden;padding:.125rem 0 .125rem 1.25rem;position:relative;text-overflow:ellipsis;user-select:none;white-space:nowrap}.go-Tree>li>a,.go-Tree a[aria-level="1"]{display:block;font-size:1rem;font-weight:500;line-height:2.5rem;padding:0 1rem}.go-Tree a:focus,.go-Tree a:hover{text-decoration:underline;z-index:1}.go-Tree a[aria-selected=true]{color:var(--color-text);font-weight:500}.go-Tree a[aria-level="1"][aria-selected=true],.go-Tree a[aria-level="1"][aria-expanded=true]{background-color:var(--color-background-accented)}.go-Tree a[aria-level="3"][aria-expanded=true]{margin-bottom:.375em}.go-Tree a[aria-level="2"]{margin-bottom:.25rem;position:relative}.go-Tree a[aria-level="3"]{padding-left:2.5rem}.go-Tree a[aria-level="4"]{border-left:.125rem solid var(--color-background-accented);margin-left:2.5rem;padding-left:.5rem}.go-Tree a[aria-selected=true][aria-level="2"]:not([aria-expanded]):before,.go-Tree a[aria-selected=true][aria-level="3"]:not([aria-expanded]):before{background-color:var(--color-brand-primary);border-radius:50%;content:"";display:block;height:.3125rem;left:.4688rem;position:absolute;top:.75rem;width:.3125rem}.go-Tree a[aria-expanded][aria-owns][aria-level="2"]:before,.go-Tree a[aria-expanded][aria-owns][aria-level="3"]:before{border-bottom:.25rem solid transparent;border-left:.25rem solid var(--color-border);border-right:0;border-top:.25rem solid transparent;content:"";display:block;height:0;left:.5rem;position:absolute;top:.625rem;transition:transform .1s linear;width:0}.go-Tree a[aria-expanded=true][aria-level="2"]:before,.go-Tree a[aria-expanded=true][aria-level="3"]:before{transform:rotate(90deg)}.go-Tree a[aria-expanded][aria-level="3"]:not([empty]):before,.go-Tree a[aria-selected][aria-level="3"]:not([empty]):before{left:1.5rem;top:.75rem}.go-Tree a[aria-selected=true][aria-level="4"]{border-left:.125rem solid var(--color-brand-primary)}.go-TabNav{margin:0 0 .5rem}.go-TabNav ul{display:flex;gap:2rem}.go-TabNav li{border-bottom:.25rem transparent solid;display:flex;font-size:1rem;height:2.375rem;padding:0 .25rem}.go-TabNav li[aria-current]{border-color:var(--color-brand-primary)}.go-TabNav li:hover{border-color:var(--color-brand-primary)}.go-TabNav a{align-items:center;color:var(--color-text-subtle);display:inline-flex}.go-TabNav li:hover a{text-decoration:none}.go-TabNav li[aria-current] a{color:var(--color-text)}.go-Tooltip{border-radius:var(--border-radius);cursor:pointer;display:inline-block;position:relative}.go-Tooltip>summary{list-style:none}.go-Tooltip>summary::-webkit-details-marker,.go-Tooltip>summary::marker{display:none}.go-Tooltip>summary>img{vertical-align:text-bottom}.go-Tooltip p{background:var(--color-background) 80%;border:var(--border);border-radius:var(--border-radius);color:var(--color-text);font-size:.75rem;letter-spacing:.01875rem;line-height:1rem;padding:.5rem;position:absolute;top:1.5rem;white-space:normal;width:12rem;z-index:100}:root{--gutter: 1rem;--gap: 1rem;--scroll-margin: calc( var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 2rem );--border: .0625rem solid var(--color-border);--border-radius: .25rem;--box-shadow: 0 0 .375rem 0 rgb(0 0 0 / 25%);--focus-box-shadow: 0 0 .0625rem .0625rem rgba(0, 112, 210, .6)}[data-theme=dark]{--box-shadow: 0 .3125rem .9375rem rgb(0 0 0 / 45%)}@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){--box-shadow: 0 .3125rem .9375rem rgb(0 0 0 / 45%)}}@media (min-width: 50rem){:root{--gutter: 1.5rem;--gap: 2rem;--scroll-margin: calc( var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 1rem )}}@media (min-width: 80rem){:root{--gutter: 2rem}}@media (min-width: 112rem){:root{--gutter: 2.5rem}}*:target{scroll-margin-top:var(--scroll-margin)}body{background-color:var(--color-background);display:flex;flex-direction:column;min-height:100vh;min-width:23.5rem;-webkit-overflow-scrolling:touch}.go-Container{display:flex;flex-direction:column;flex-grow:1;height:100%;margin-bottom:5rem}.go-Content{display:flex;flex-flow:column;gap:1rem;margin:0 auto;max-width:63rem;min-height:32rem;padding:2rem var(--gutter);width:100%}.go-Content--center{justify-content:center;margin:auto}
 /*# sourceMappingURL=frontend.min.css.map */
diff --git a/static/frontend/frontend.min.css.map b/static/frontend/frontend.min.css.map
index 947f207..ad4231a 100644
--- a/static/frontend/frontend.min.css.map
+++ b/static/frontend/frontend.min.css.map
@@ -1,7 +1,7 @@
 {
   "version": 3,
   "sources": ["../shared/reset.css", "../shared/typography/typography.css", "../shared/button/button.css", "../shared/breadcrumb/breadcrumb.css", "../shared/carousel/carousel.css", "../shared/chip/chip.css", "../shared/clipboard/clipboard.css", "../shared/color/color.css", "../shared/footer/footer.css", "../shared/form/form.css", "../shared/gopher/gopher.css", "../shared/header/header.css", "../shared/icon/icon.css", "../shared/message/message.css", "../../third_party/dialog-polyfill/dialog-polyfill.css", "../shared/modal/modal.css", "../shared/outline/tree.css", "../shared/tabnav/tabnav.css", "../shared/tooltip/tooltip.css", "../shared/shared.css"],
-  "sourcesContent": ["/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/*!\n * http://meyerweb.com/eric/tools/css/reset/\n * v2.0 | 20110126\n * License: none (public domain)\n */\n\nhtml,\nbody,\nbutton,\ndiv,\nspan,\napplet,\nobject,\niframe,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\ninput,\np,\nblockquote,\npre,\na,\nabbr,\nacronym,\naddress,\nbig,\ncite,\ncode,\ndel,\ndfn,\ndialog,\nem,\nimg,\nins,\nkbd,\nq,\ns,\nsamp,\nsmall,\nstrike,\nstrong,\nsub,\nsup,\ntt,\nvar,\nb,\nu,\ni,\ncenter,\ndl,\ndt,\ndd,\nol,\nul,\nli,\nfieldset,\nform,\nlabel,\nlegend,\ntable,\ncaption,\ntbody,\ntfoot,\nthead,\ntr,\nth,\ntd,\narticle,\naside,\ncanvas,\ndetails,\nembed,\nfigure,\nfigcaption,\nfooter,\nheader,\nhgroup,\nmenu,\nnav,\noutput,\nruby,\nsection,\nsummary,\ntime,\nmark,\naudio,\nvideo {\n  border: 0;\n  font: inherit;\n  font-size: 100%;\n  margin: 0;\n  padding: 0;\n  vertical-align: baseline;\n}\n\n/* HTML5 display-role reset for older browsers */\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmenu,\nnav,\nsection {\n  display: block;\n}\nbody {\n  line-height: 1;\n}\nol,\nul {\n  list-style: none;\n}\nblockquote,\nq {\n  quotes: none;\n}\nblockquote::before,\nblockquote::after,\nq::before,\nq::after {\n  content: '';\n  content: none;\n}\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\n*,\n::before,\n::after {\n  box-sizing: border-box;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nbody {\n  color: var(--color-text);\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif,\n    'Apple Color Emoji', 'Segoe UI Emoji';\n  font-size: 1rem;\n  line-height: normal;\n}\nh1 {\n  font-size: 1.5rem;\n}\nh2 {\n  font-size: 1.375rem;\n}\nh3 {\n  font-size: 1.25rem;\n}\nh4 {\n  font-size: 1.125rem;\n}\nh5 {\n  font-size: 1rem;\n}\nh6 {\n  font-size: 0.875rem;\n}\n\nh1,\nh2,\nh3,\nh4 {\n  font-weight: 600;\n  line-height: 1.25em;\n  word-break: break-word;\n}\nh5,\nh6 {\n  font-weight: 500;\n  line-height: 1.3em;\n  word-break: break-word;\n}\n\nhr {\n  border: none;\n  border-bottom: var(--border);\n  margin: 0;\n  width: 100%;\n}\n\np {\n  font-size: 1rem;\n  line-height: 1.5rem;\n  max-width: 60rem;\n}\nstrong {\n  font-weight: 600;\n}\n\n.go-textSubtle {\n  color: var(--color-text-subtle);\n}\n.go-textTitle {\n  font-size: 1.125rem;\n  font-weight: 600;\n  line-height: 1.25rem;\n}\n.go-textLabel {\n  font-size: 0.875rem;\n  font-weight: 600;\n  line-height: 1rem;\n}\n.go-textPagination {\n  font-size: 0.875rem;\n  line-height: 1rem;\n}\ncode,\npre,\ntextarea.code {\n  font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;\n  font-size: 0.875rem;\n  line-height: 1.5em;\n}\npre,\ntextarea.code {\n  background-color: var(--color-background-accented);\n  border: var(--border);\n  border-radius: var(--border-radius);\n  color: var(--color-text);\n  overflow-x: auto;\n  padding: 0.625rem;\n  tab-size: 4;\n  white-space: pre;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n  font: inherit;\n}\n\na,\na:link,\na:visited {\n  color: var(--color-brand-primary);\n  text-decoration: none;\n}\na:hover,\na:hover > * {\n  color: var(--color-brand-primary);\n  text-decoration: underline;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nbutton:focus:not([disabled]) {\n  border-color: var(--color-brand-primary);\n  -webkit-box-shadow: var(--focus-box-shadow);\n  box-shadow: var(--focus-box-shadow);\n  outline: transparent;\n}\n\n.go-Button {\n  align-items: center;\n  background-color: var(--color-button);\n  border: 0.0625rem solid transparent;\n  border-radius: var(--border-radius);\n  color: var(--color-button-text);\n  cursor: pointer;\n  display: inline-flex;\n  font-weight: 500;\n  gap: 0.25rem;\n}\n.go-Button:not(.go-Button--inline) {\n  padding: 0.5rem;\n}\n\n.go-Button--accented {\n  background-color: var(--color-button-accented);\n  color: var(--color-button-accented-text);\n}\n.go-Button--inverted,\n.go-Button--text,\n.go-Button--inline {\n  background-color: var(--color-button-inverted);\n  color: var(--color-button-inverted-text);\n}\n.go-Button--inline {\n  background-color: transparent;\n}\n\n.go-Button--inverted {\n  border: var(--border);\n}\n\n.go-Button:hover {\n  box-shadow: var(--focus-box-shadow);\n  filter: contrast(0.95);\n}\n.go-Button--inline:hover {\n  box-shadow: none;\n  text-decoration: underline var(--color-button-inverted-text);\n}\n.go-Button:focus {\n  filter: contrast(0.95);\n}\n.go-Button--inverted:focus {\n  border-color: var(--color-button-inverted-text);\n}\n.go-Button:active {\n  box-shadow: none;\n  filter: contrast(0.85);\n}\n\n.go-Button:disabled {\n  background-color: var(--color-button-disabled);\n  box-shadow: none;\n  color: var(--color-button-text-disabled);\n  cursor: initial;\n  filter: none;\n  text-decoration: none;\n}\n.go-Button--accented:disabled {\n  background-color: var(--color-button-accented-disabled);\n  color: var(--color-button-accented-text-disabled);\n}\n.go-Button--inverted:disabled,\n.go-Button--text:disabled,\n.go-Button--inline:disabled {\n  background-color: var(--color-button-inverted-disabled);\n  color: var(--color-button-inverted-text-disabled);\n}\n.go-Button--inline:disabled {\n  background-color: transparent;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Breadcrumb ol {\n  line-height: 1.5rem;\n  white-space: initial;\n}\n.go-Breadcrumb li {\n  align-items: center;\n  color: var(--color-text-subtle);\n  display: inline-flex;\n  font-size: 0.875rem;\n}\n.go-Breadcrumb li:not(:last-child)::after {\n  content: '>';\n  padding: 0 0.5rem;\n}\n.go-Breadcrumb li:last-child > a {\n  color: var(--color-text-subtle);\n}\n.go-Breadcrumb li > .go-Clipboard {\n  margin: 0 0.5rem;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Carousel {\n  align-items: center;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n  text-align: center;\n}\n.go-Carousel-slide {\n  margin: 0.5rem 3rem;\n}\n.go-Carousel-slide[aria-hidden] {\n  display: none;\n}\n.go-Carousel-prevSlide {\n  left: 0;\n}\n.go-Carousel-nextSlide {\n  right: 0;\n}\n.go-Carousel-prevSlide,\n.go-Carousel-nextSlide {\n  background-color: transparent;\n  border-radius: var(--border-radius);\n  font-size: 1.5rem;\n  height: 2.75rem;\n  margin-top: -1.375rem;\n  opacity: 0;\n  position: absolute;\n  top: 50%;\n  width: 2.75rem;\n}\n.go-Carousel-prevSlide:hover,\n.go-Carousel-nextSlide:hover {\n  background-color: var(--color-background-accented);\n  cursor: pointer;\n}\n.go-Carousel:hover .go-Carousel-prevSlide,\n.go-Carousel:hover .go-Carousel-nextSlide,\n.go-Carousel:focus-within .go-Carousel-prevSlide,\n.go-Carousel:focus-within .go-Carousel-nextSlide {\n  opacity: 1;\n}\n.go-Carousel-dots {\n  display: flex;\n  font-size: 0.4375rem;\n  gap: 0.5rem;\n}\n.go-Carousel-dot {\n  background-color: var(--color-border);\n  border-radius: 2rem;\n  height: 0.4375rem;\n  width: 0.4375rem;\n}\n.go-Carousel-dot--active,\n.go-Carousel-dot:hover {\n  background-color: var(--color-text-subtle);\n}\n.go-Carousel-obscured {\n  border: 0;\n  clip: rect(0 0 0 0);\n  height: 0.0625rem;\n  margin: -0.0625rem;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 0.0625rem;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Chip {\n  background: var(--color-button);\n  border: 0.0625rem solid var(--color-button);\n  border-radius: 1.25rem;\n  color: var(--color-button-text);\n  font-size: 0.75rem;\n  padding: 0.125rem 0.625rem;\n}\n.go-Chip--accented {\n  background: var(--color-button-accented);\n  border: 0.0625rem solid var(--color-button-accented);\n  color: var(--color-button-accented-text);\n}\n.go-Chip--inverted {\n  background: var(--color-button-inverted);\n  border: var(--border);\n  color: var(--color-text);\n}\n.go-Chip--highlighted {\n  background: var(--color-background-highlighted-link);\n  border-color: var(--color-background-highlighted-link);\n  color: var(--color-brand-primary);\n}\n.go-Chip--alert {\n  background: var(--pink);\n  border: 0.0625rem solid var(--pink);\n  color: var(--color-text-inverted);\n}\n.go-Chip--vuln {\n  background: var(--pink-light);\n  border: 0.0625rem solid var(--pink-light);\n  color: var(--color-text-inverted);\n}\n.go-Chip--subtle {\n  background-color: var(--color-background-accented);\n  border-color: transparent;\n  color: var(--color-text-subtle);\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Clipboard {\n  position: relative;\n}\n.go-Clipboard::before {\n  background-color: var(--color-background-inverted);\n  border-radius: var(--border-radius);\n  color: var(--color-text-inverted);\n  content: attr(data-tooltip);\n  display: block;\n  font-size: 0.9em;\n  left: calc(100% + 0.125rem);\n  padding: 0.25rem 0.3rem;\n  position: absolute;\n  text-transform: uppercase;\n  top: 0.125rem;\n  white-space: nowrap;\n  z-index: 1000;\n}\n.go-Clipboard::after {\n  border-bottom: 0.25rem solid transparent;\n  border-left: 0;\n  border-right: 0.25rem solid var(--color-background-inverted);\n  border-top: 0.25rem solid transparent;\n  content: '';\n  display: block;\n  position: absolute;\n  right: -0.125rem;\n  top: 0.5625rem;\n  z-index: 1000;\n}\n.go-Clipboard:not([data-tooltip])::before,\n.go-Clipboard:not([data-tooltip])::after,\n.go-Clipboard[data-tooltip='']::before,\n.go-Clipboard[data-tooltip='']::after {\n  display: none;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n:root {\n  /* Colors */\n  --gray-1: #202224;\n  --gray-2: #3e4042;\n  --gray-3: #555759;\n  --gray-4: #6e7072;\n  --gray-5: #848688;\n  --gray-6: #aaacae;\n  --gray-7: #c6c8ca;\n  --gray-8: #dcdee0;\n  --gray-9: #f0f1f2;\n  --gray-10: #f8f8f8;\n  --turq-light: #5dc9e2;\n  --turq-med: #50b7e0;\n  --turq-dark: #007d9c;\n  --blue: #bfeaf4;\n  --blue-light: #f2fafd;\n  --black: #000;\n  --green: #3a6e11;\n  --green-light: #5fda64;\n  --pink: #ce3262;\n  --pink-light: #fdecf1;\n  --purple: #542c7d;\n  --slate: #253443; /* Footer background. */\n  --white: #fff;\n  --yellow: #fddd00;\n  --yellow-light: #fff8cc;\n\n  /* Color Intents */\n  --color-brand-primary: var(--turq-dark);\n  --color-background: var(--white);\n  --color-background-inverted: var(--slate);\n  --color-background-accented: var(--gray-10);\n  --color-background-highlighted: var(--blue);\n  --color-background-highlighted-link: var(--blue-light);\n  --color-background-info: var(--gray-9);\n  --color-background-warning: var(--yellow-light);\n  --color-background-alert: var(--pink-light);\n  --color-border: var(--gray-7);\n  --color-text: var(--gray-1);\n  --color-text-subtle: var(--gray-4);\n  --color-text-inverted: var(--white);\n  --color-code-comment: var(--green);\n\n  /* Interactive Colors */\n  --color-input: var(--color-background);\n  --color-input-text: var(--color-text);\n  --color-button: var(--turq-dark);\n  --color-button-disabled: var(--gray-9);\n  --color-button-text: var(--white);\n  --color-button-text-disabled: var(--gray-3);\n  --color-button-inverted: var(--color-background);\n  --color-button-inverted-disabled: var(--color-background);\n  --color-button-inverted-text: var(--color-brand-primary);\n  --color-button-inverted-text-disabled: var(--color-text-subtle);\n  --color-button-accented: var(--yellow);\n  --color-button-accented-disabled: var(--gray-9);\n  --color-button-accented-text: var(--gray-1);\n  --color-button-accented-text-disabled: var(--gray-3);\n}\n\n[data-theme='dark'] {\n  --color-brand-primary: var(--turq-med);\n  --color-background: var(--gray-1);\n  --color-background-accented: var(--gray-2);\n  --color-background-highlighted: var(--gray-2);\n  --color-background-highlighted-link: var(--gray-2);\n  --color-background-info: var(--gray-3);\n  --color-background-warning: var(--yellow);\n  --color-background-alert: var(--pink);\n  --color-border: var(--gray-4);\n  --color-text: var(--gray-9);\n  --color-text-subtle: var(--gray-7);\n  --color-code-comment: var(--green-light);\n}\n@media (prefers-color-scheme: dark) {\n  :root:not([data-theme='light']) {\n    --color-brand-primary: var(--turq-med);\n    --color-background: var(--gray-1);\n    --color-background-accented: var(--gray-2);\n    --color-background-highlighted: var(--gray-2);\n    --color-background-highlighted-link: var(--gray-2);\n    --color-background-info: var(--gray-3);\n    --color-background-warning: var(--yellow);\n    --color-background-alert: var(--pink);\n    --color-border: var(--gray-4);\n    --color-text: var(--gray-9);\n    --color-text-subtle: var(--gray-7);\n    --color-code-comment: var(--green-light);\n  }\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Footer {\n  background-color: var(--color-background-inverted);\n  color: var(--color-text-inverted);\n  font-size: 0.875rem;\n  width: 100%;\n}\n.go-Footer-links {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: space-between;\n  margin: auto;\n  max-width: 75.75rem;\n  padding: 2rem 1.5rem 2.625rem 1.5rem;\n}\n.go-Footer-linkColumn {\n  flex: 0 0 9.5rem;\n}\n.go-Footer .go-Footer-link {\n  color: var(--color-text-inverted);\n  display: flex;\n  flex: 1;\n  font-size: 0.875rem;\n  line-height: 2rem;\n}\n.go-Footer .go-Footer-link--primary {\n  font-size: 1.125rem;\n  line-height: 1.75rem;\n  margin-bottom: 0.5rem;\n  margin-top: 0.75rem;\n}\n.go-Footer-bottom {\n  align-items: center;\n  border-top: var(--border);\n  display: flex;\n  margin: 0 1.5rem;\n  min-height: 4.125rem;\n}\n.go-Footer-gopher {\n  align-self: flex-end;\n  height: 3.147rem;\n  width: 5rem;\n}\n.go-Footer-listRow {\n  display: flex;\n  flex: 1;\n  flex-wrap: wrap;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  text-align: center;\n}\n.go-Footer-listItem {\n  align-items: center;\n  display: flex;\n  flex: 1 100%;\n  justify-content: center;\n  margin: 0.4rem 0;\n  padding: 0 1rem;\n}\n.go-Footer-listItem a:link,\n.go-Footer-listItem a:visited {\n  color: var(--color-text-inverted);\n}\n\n.go-Footer-googleLogo {\n  align-self: flex-end;\n  height: 1.5rem;\n  margin-bottom: 1.3rem;\n  text-align: right;\n}\n.go-Footer-googleLogoImg {\n  height: 1.5rem;\n  width: 4.529rem;\n}\n\n@media only screen and (min-width: 52rem) {\n  .go-Footer-listItem {\n    flex: initial;\n  }\n  .go-Footer-listItem + .go-Footer-listItem {\n    border-left: var(--border);\n  }\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nselect:focus:not([disabled]),\ninput:focus:not([disabled]) {\n  border-color: var(--color-brand-primary);\n  -webkit-box-shadow: var(--focus-box-shadow);\n  box-shadow: var(--focus-box-shadow);\n  outline: transparent;\n  z-index: 2;\n}\n\ninput::placeholder {\n  color: var(--color-text-subtle);\n}\n\n.go-Form {\n  align-items: start;\n  display: flex;\n  flex-direction: column;\n  gap: 1rem;\n}\n\n.go-Label {\n  display: flex;\n  flex-direction: column;\n  gap: 0.5rem;\n}\n.go-Label--inline {\n  align-items: center;\n  flex-direction: row;\n}\n.go-Label legend {\n  margin-bottom: 0.5rem;\n}\n.go-Label--inline legend {\n  float: left;\n  margin-bottom: 0;\n}\n.go-Input,\n.go-Select {\n  background: var(--color-input);\n  border: var(--border);\n  border-radius: var(--border-radius);\n  color: var(--color-input-text);\n}\n.go-Input {\n  padding: 0.40625rem 0.5rem;\n}\n.go-Select {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  background: url('/static/shared/icon/arrow_drop_down_gm_grey_24dp.svg') right no-repeat;\n  background-color: var(--color-background);\n  background-position: right center;\n  border-radius: var(--border-radius);\n  margin: 0;\n  padding: 0.34375rem 1.25rem 0.34375rem 0.5rem;\n}\n\n.go-InputGroup {\n  display: flex;\n}\n.go-InputGroup .go-Input {\n  flex: 1;\n}\n.go-InputGroup > :not(:first-child, :last-child) {\n  border-radius: 0;\n  margin-left: -0.0625rem;\n}\n.go-InputGroup > :first-child {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.go-InputGroup > :last-child {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n  margin-left: -0.0625rem;\n}\n.go-InputGroup > *:hover,\n.go-InputGroup > *:focus {\n  z-index: 1;\n}\n\n.go-ShortcutKey {\n  display: flex;\n  position: relative;\n}\n.go-ShortcutKey .go-Input {\n  flex-grow: 1;\n}\n.go-ShortcutKey::after {\n  align-self: center;\n  background-color: var(--color-background-accented);\n  border-radius: 0.5rem;\n  color: var(--gray-6);\n  content: attr(data-shortcut);\n  content: attr(data-shortcut) / attr(data-shortcut-alt);\n  display: none;\n  font-size: 0.75rem;\n  padding: 0.0625rem 0;\n  position: absolute;\n  right: 0.75rem;\n  text-align: center;\n  width: 1.5rem;\n  z-index: 1;\n}\n@media only screen and (min-width: 52rem) {\n  .go-ShortcutKey::after {\n    display: initial;\n  }\n}\n", "/*!\n * Copyright 2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-GopherMessage img {\n  display: block;\n  height: 15rem;\n  margin: 0 auto;\n  padding: 1.25rem 0;\n  width: 15rem;\n}\n.go-GopherMessage p {\n  font-weight: 600;\n  margin: auto;\n  text-align: center;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Banner {\n  background-color: var(--gray-1);\n\n  /**\n   * Only show on wide viewports so the\n   * text never wraps or gets cut off.\n   */\n  display: none;\n}\n.go-Banner-inner {\n  align-items: center;\n  display: flex;\n  justify-content: space-between;\n  margin: 0 auto;\n  max-width: 75.75rem;\n  min-height: 2.5rem;\n  padding: 0.5rem var(--gutter);\n}\n.Site--wide .go-Banner-inner {\n  max-width: 98rem;\n}\n.go-Banner--full .go-Banner-inner {\n  max-width: unset;\n}\n.go-Banner-message {\n  color: var(--white);\n  margin-right: 1.25rem;\n}\n.go-Banner-action:link,\n.go-Banner-action:visited {\n  color: var(--white);\n  text-decoration: underline;\n  white-space: nowrap;\n}\n@media only screen and (min-width: 52rem) {\n  .go-Banner {\n    display: block;\n  }\n}\n\n.go-Header {\n  background: #007d9c;\n  border-bottom: none;\n  box-shadow: 0 0.0625rem 0.125rem rgba(171, 171, 171, 0.3);\n  top: 0;\n  width: 100%;\n  z-index: 10;\n}\n.go-Header-inner {\n  margin: 0 auto;\n  max-width: 75.75rem;\n  padding: 0 var(--gutter);\n}\n.Site--wide .go-Header-inner {\n  max-width: 98rem;\n}\n.go-Header--full .go-Header-inner {\n  max-width: initial;\n}\n.go-Header-nav {\n  align-items: center;\n  display: flex;\n  height: 3.5rem;\n  justify-content: space-between;\n}\n.go-Header-rightContent {\n  align-items: center;\n  display: flex;\n  height: 100%;\n  justify-content: flex-end;\n  width: 100%;\n}\n.go-Header-rightContent form {\n  flex-grow: 1;\n}\n.go-Header-inner--dark {\n  border-bottom: none;\n  color: var(--white);\n}\n.go-Header-logo {\n  display: block;\n  height: 2rem;\n  margin-right: 2.25rem;\n  width: 5.125rem;\n}\n.go-Header-logo--hidden {\n  display: none;\n}\n.go-Header-menuItem {\n  display: none;\n}\n.go-Header-menu {\n  align-items: stretch;\n  display: flex;\n  height: 100%;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n@media only screen and (min-width: 65rem) {\n  .go-Header-menuItem {\n    align-items: stretch;\n    display: inline-flex;\n    flex: none;\n  }\n  .go-Header-menu {\n    justify-content: flex-end;\n  }\n  .go-Header-navOpen {\n    display: none;\n  }\n}\n.go-Header-menuItem a:link,\n.go-Header-menuItem a:visited {\n  align-items: center;\n  border-bottom: 0.1875rem solid transparent;\n  border-top: 0.1875rem solid transparent; /* To ensure the text remains centered. */\n  color: var(--gray-2);\n  display: inline-flex;\n  margin: 0 0.3125rem;\n  padding: 0 0.9375rem;\n  text-align: center;\n  text-decoration: none;\n  width: 100%;\n}\n.go-Header-menuItem--active a:link,\n.go-Header-menuItem--active a:visited {\n  border-bottom-color: var(--turq-med);\n  font-weight: bold;\n}\n.go-Header-menuItem a:hover {\n  border-bottom-color: var(--white);\n  color: var(--gray-2);\n}\n.go-NavigationDrawer-listItem a:link,\n.go-NavigationDrawer-listItem a:visited {\n  display: block;\n  margin: 0 1rem;\n  padding: 0.5rem;\n}\n.go-Header-inner--dark .go-Header-menuItem a:link,\n.go-Header-inner--dark .go-Header-menuItem a:visited {\n  color: var(--white);\n}\n\n.go-Header-navOpen {\n  background: no-repeat center/2rem url('/images/menu-24px.svg');\n  border: none;\n  height: 2.5rem;\n  margin-left: 1rem;\n  width: 2.5rem;\n}\n.go-Header-navOpen--hidden {\n  display: none;\n}\n.go-Header-navOpen--white {\n  background: no-repeat center/2rem url('/static/shared/icon/menu_gm_grey_24dp.svg');\n  filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg)\n    brightness(103%) contrast(107%);\n}\n\n.go-SearchForm--expanded {\n  flex-grow: 1;\n}\n.go-SearchForm-form {\n  display: none;\n}\n.go-SearchForm-form::after {\n  right: 2.75rem;\n}\n.go-SearchForm--expanded .go-SearchForm-form {\n  display: flex;\n}\n.go-SearchForm-expandSearch {\n  appearance: none;\n  background: none;\n  font-size: 1.5rem;\n}\n.go-SearchForm--expanded .go-SearchForm-expandSearch {\n  display: none;\n}\n\n@media only screen and (min-width: 32rem) {\n  .go-Header-rightContent {\n    width: 100%;\n  }\n  .go-SearchForm {\n    flex: 1;\n  }\n  .go-SearchForm-form {\n    display: flex;\n  }\n  .go-SearchForm-expandSearch {\n    display: none;\n  }\n  .go-Header-logo--hidden {\n    display: initial;\n  }\n}\n\n.go-NavigationDrawer {\n  background: var(--white);\n  height: 100%;\n  left: auto;\n  max-width: 27rem;\n  position: fixed;\n  right: 0;\n  top: 0;\n  transform: translateX(100%);\n  transition: transform 100ms ease-in-out;\n  width: 85%;\n  z-index: 30;\n}\n@media only screen and (min-width: 65rem) {\n  .go-NavigationDrawer {\n    display: none;\n  }\n}\n.go-NavigationDrawer.is-active {\n  transform: translateX(0);\n}\n.go-NavigationDrawer-header {\n  align-items: center;\n  display: flex;\n  justify-content: space-between;\n}\n.go-NavigationDrawer-logo {\n  display: block;\n  height: 2rem;\n  margin: 1rem 1rem;\n  width: 5.125rem;\n}\n.go-NavigationDrawer-list {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n.go-NavigationDrawer-listItem {\n  font-size: 1.125rem;\n  margin: 0 0.5rem;\n}\n.go-NavigationDrawer-listItem--active {\n  background-color: var(--blue);\n  border-radius: 0.4rem;\n}\n.go-NavigationDrawer-scrim {\n  display: none;\n  height: 100%;\n  left: 0;\n  position: fixed;\n  top: 0;\n  width: 100%;\n  z-index: 20;\n}\n.go-NavigationDrawer.is-active + .go-NavigationDrawer-scrim {\n  background-color: var(--gray-1);\n  display: block;\n  opacity: 0.32;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Icon {\n  filter: none;\n  height: 1.125em;\n  vertical-align: text-bottom;\n  width: auto;\n}\n.go-Icon--accented {\n  filter: brightness(0) invert(45%) sepia(94%) saturate(6735%) hue-rotate(176deg) brightness(94%)\n    contrast(101%);\n}\n.go-Icon--inverted {\n  filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg)\n    brightness(103%) contrast(107%);\n}\n\n[data-theme='dark'] .go-Icon:not(.go-Icon--accented) {\n  filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg)\n    brightness(103%) contrast(107%);\n}\n[data-theme='dark'] .go-Icon--accented {\n  filter: brightness(0) invert(69%) sepia(46%) saturate(466%) hue-rotate(153deg) brightness(90%)\n    contrast(88%);\n}\n@media (prefers-color-scheme: dark) {\n  :root:not([data-theme='light']) .go-Icon:not(.go-Icon--accented) {\n    filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg)\n      brightness(103%) contrast(107%);\n  }\n  :root:not([data-theme='light']) .go-Icon--accented {\n    filter: brightness(0) invert(57%) sepia(63%) saturate(4864%) hue-rotate(160deg) brightness(100%)\n      contrast(101%);\n  }\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Message {\n  color: var(--color-text);\n  font-size: 0.875rem;\n  line-height: 1.5rem;\n  padding: 0 var(--gutter);\n  width: 100%;\n}\n.go-Message--notice {\n  background-color: var(--color-background-info);\n}\n.go-Message--warning {\n  background-color: var(--color-background-warning);\n  color: var(--gray-1);\n}\n.go-Message--alert {\n  background-color: var(--color-background-alert);\n}\n\n.go-Message > .go-Icon {\n  vertical-align: text-top;\n}\n\n[data-theme='dark'] .go-Message--warning .go-Icon {\n  filter: none;\n}\n@media (prefers-color-scheme: dark) {\n  :root:not([data-theme='light']) .go-Message--warning .go-Icon {\n    filter: none;\n  }\n}\n", "dialog {\n  position: absolute;\n  left: 0; right: 0;\n  width: -moz-fit-content;\n  width: -webkit-fit-content;\n  width: fit-content;\n  height: -moz-fit-content;\n  height: -webkit-fit-content;\n  height: fit-content;\n  margin: auto;\n  border: solid;\n  padding: 1em;\n  background: white;\n  color: black;\n  display: block;\n}\n\ndialog:not([open]) {\n  display: none;\n}\n\ndialog + .backdrop {\n  position: fixed;\n  top: 0; right: 0; bottom: 0; left: 0;\n  background: rgba(0,0,0,0.1);\n}\n\n._dialog_overlay {\n  position: fixed;\n  top: 0; right: 0; bottom: 0; left: 0;\n}\n\ndialog.fixed {\n  position: fixed;\n  top: 50%;\n  transform: translate(0, -50%);\n}", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n@import url('../../../third_party/dialog-polyfill/dialog-polyfill.css');\n\n.go-Modal {\n  background: var(--color-background);\n  border: var(--border);\n  border-radius: var(--border-radius);\n  bottom: 0;\n  box-shadow: var(--box-shadow);\n  color: var(--color-text);\n  display: flex;\n  flex-direction: column;\n  gap: 1rem;\n  max-height: 100%;\n  max-width: 100%;\n  position: fixed;\n  top: 0;\n}\n.go-Modal > form {\n  display: contents;\n}\n.go-Modal--small {\n  width: 20rem;\n}\n.go-Modal--md {\n  width: 30rem;\n}\n.go-Modal--lg {\n  width: 40rem;\n}\n.go-Modal-header {\n  display: flex;\n  justify-content: space-between;\n}\n.go-Modal-header h2 {\n  font-size: 1.15rem;\n  line-height: 1.25rem;\n}\n.go-Modal-body {\n  flex-grow: 1;\n  min-height: 2rem;\n  min-width: 18rem;\n}\n.go-Modal-actions {\n  text-align: right;\n}\n\n/* Safari only */\n@media not all and (min-resolution: 0.001dpcm) {\n  @supports (-webkit-appearance: none) {\n    .go-Modal {\n      padding-bottom: 0;\n    }\n  }\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Tree {\n  --js-tree-height: 0;\n\n  display: flex;\n  flex-direction: column;\n}\n\n.go-Tree ul {\n  list-style: none;\n  padding-left: 0;\n}\n.go-Tree li:last-of-type {\n  padding-bottom: 0.25rem;\n}\n.go-Tree a + ul {\n  display: none;\n}\n.go-Tree a[aria-expanded='true'] + ul[role='group'] {\n  display: block;\n}\n.go-Tree a[aria-level='1'] + ul[role='group'] {\n  max-height: calc(\n    100vh - var(--js-tree-height, 0) - var(--js-sticky-header-height, 3.5rem) - 5rem\n  );\n  overflow-y: auto;\n  padding: 0.5rem 0.25rem 0 0.25rem;\n}\n.go-Tree a {\n  color: var(--color-text-subtle);\n  display: block;\n  line-height: 1.5rem;\n  overflow: hidden;\n  padding: 0.125rem 0 0.125rem 1.25rem;\n  position: relative;\n  text-overflow: ellipsis;\n  user-select: none;\n  white-space: nowrap;\n}\n.go-Tree > li > a,\n.go-Tree a[aria-level='1'] {\n  display: block;\n  font-size: 1rem;\n  font-weight: 500;\n  line-height: 2.5rem;\n  padding: 0 1rem;\n}\n.go-Tree a:focus,\n.go-Tree a:hover {\n  text-decoration: underline;\n  z-index: 1;\n}\n.go-Tree a[aria-selected='true'] {\n  color: var(--color-text);\n  font-weight: 500;\n}\n.go-Tree a[aria-level='1'][aria-selected='true'],\n.go-Tree a[aria-level='1'][aria-expanded='true'] {\n  background-color: var(--color-background-accented);\n}\n.go-Tree a[aria-level='3'][aria-expanded='true'] {\n  margin-bottom: 0.375em;\n}\n.go-Tree a[aria-level='2'] {\n  margin-bottom: 0.25rem;\n  position: relative;\n}\n.go-Tree a[aria-level='3'] {\n  padding-left: 2.5rem;\n}\n.go-Tree a[aria-level='4'] {\n  border-left: 0.125rem solid var(--color-background-accented);\n  margin-left: 2.5rem;\n  padding-left: 0.5rem;\n}\n.go-Tree a[aria-selected='true'][aria-level='2']:not([aria-expanded])::before,\n.go-Tree a[aria-selected='true'][aria-level='3']:not([aria-expanded])::before {\n  background-color: var(--color-brand-primary);\n  border-radius: 50%;\n  content: '';\n  display: block;\n  height: 0.3125rem;\n  left: 0.4688rem;\n  position: absolute;\n  top: 0.75rem;\n  width: 0.3125rem;\n}\n.go-Tree a[aria-expanded][aria-owns][aria-level='2']::before,\n.go-Tree a[aria-expanded][aria-owns][aria-level='3']::before {\n  border-bottom: 0.25rem solid transparent;\n  border-left: 0.25rem solid var(--color-border);\n  border-right: 0;\n  border-top: 0.25rem solid transparent;\n  content: '';\n  display: block;\n  height: 0;\n  left: 0.5rem;\n  position: absolute;\n  top: 0.625rem;\n  transition: transform 0.1s linear;\n  width: 0;\n}\n.go-Tree a[aria-expanded='true'][aria-level='2']::before,\n.go-Tree a[aria-expanded='true'][aria-level='3']::before {\n  transform: rotate(90deg);\n}\n.go-Tree a[aria-expanded][aria-level='3']:not([empty])::before,\n.go-Tree a[aria-selected][aria-level='3']:not([empty])::before {\n  left: 1.5rem;\n  top: 0.75rem;\n}\n.go-Tree a[aria-selected='true'][aria-level='4'] {\n  border-left: 0.125rem solid var(--color-brand-primary);\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-TabNav {\n  margin: 0 0 0.5rem 0;\n}\n.go-TabNav ul {\n  display: flex;\n  gap: 2rem;\n}\n.go-TabNav li {\n  border-bottom: 0.25rem transparent solid;\n  display: flex;\n  font-size: 1rem;\n  height: 2.375rem;\n  padding: 0 0.25rem;\n}\n.go-TabNav li[aria-current] {\n  border-color: var(--color-brand-primary);\n}\n.go-TabNav li:hover {\n  border-color: var(--color-brand-primary);\n}\n.go-TabNav a {\n  align-items: center;\n  color: var(--color-text-subtle);\n  display: inline-flex;\n}\n.go-TabNav li:hover a {\n  text-decoration: none;\n}\n.go-TabNav li[aria-current] a {\n  color: var(--color-text);\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Tooltip {\n  border-radius: var(--border-radius);\n  cursor: pointer;\n  display: inline-block;\n  position: relative;\n}\n.go-Tooltip > summary {\n  list-style: none;\n}\n.go-Tooltip > summary::-webkit-details-marker,\n.go-Tooltip > summary::marker {\n  display: none;\n}\n.go-Tooltip > summary > img {\n  vertical-align: text-bottom;\n}\n.go-Tooltip p {\n  background: var(--color-background) 80%;\n  border: var(--border);\n  border-radius: var(--border-radius);\n  color: var(--color-text);\n  font-size: 0.75rem;\n  letter-spacing: 0.01875rem;\n  line-height: 1rem;\n  padding: 0.5rem;\n  position: absolute;\n  top: 1.5rem;\n  white-space: normal;\n  width: 12rem;\n  z-index: 100;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n@import url('./reset.css');\n\n/**\n * Typography should be imported first in the list below to ensure expected\n * CSS rule inheritance on text elements.\n */\n@import url('./typography/typography.css');\n@import url('./button/button.css');\n@import url('./breadcrumb/breadcrumb.css');\n@import url('./carousel/carousel.css');\n@import url('./chip/chip.css');\n@import url('./clipboard/clipboard.css');\n@import url('./color/color.css');\n@import url('./footer/footer.css');\n@import url('./form/form.css');\n@import url('./gopher/gopher.css');\n@import url('./header/header.css');\n@import url('./icon/icon.css');\n@import url('./message/message.css');\n@import url('./modal/modal.css');\n@import url('./outline/tree.css');\n@import url('./tabnav/tabnav.css');\n@import url('./tooltip/tooltip.css');\n\n:root {\n  /* Padding at the left and right of the viewport. */\n  --gutter: 1rem;\n\n  /* Margin between containers in the grid layout. */\n  --gap: 1rem;\n\n  /* The margin placed above elements scrolled to by clicking hash links. */\n  --scroll-margin: calc(\n    var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 2rem\n  );\n\n  /* Default styles for page elements. */\n  --border: 0.0625rem solid var(--color-border);\n  --border-radius: 0.25rem;\n  --box-shadow: 0 0 0.375rem 0 rgb(0 0 0 / 25%);\n  --focus-box-shadow: 0 0 0.0625rem 0.0625rem rgba(0, 112, 210, 0.6);\n}\n\n[data-theme='dark'] {\n  --box-shadow: 0 0.3125rem 0.9375rem rgb(0 0 0 / 45%);\n}\n@media (prefers-color-scheme: dark) {\n  :root:not([data-theme='light']) {\n    --box-shadow: 0 0.3125rem 0.9375rem rgb(0 0 0 / 45%);\n  }\n}\n@media (min-width: 50rem) {\n  :root {\n    --gutter: 1.5rem;\n    --gap: 2rem;\n    --scroll-margin: calc(\n      var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 1rem\n    );\n  }\n}\n@media (min-width: 80rem) {\n  :root {\n    --gutter: 2rem;\n  }\n}\n@media (min-width: 112rem) {\n  :root {\n    --gutter: 2.5rem;\n  }\n}\n\n*:target {\n  scroll-margin-top: var(--scroll-margin);\n}\n\nbody {\n  background-color: var(--color-background);\n  display: flex;\n  flex-direction: column;\n  min-height: 100vh;\n  min-width: 23.5rem;\n\n  /**\n   * This is used to programatically detect whether overflow needs to be altered\n   * to prevent jitter when focusing within fixed elements on iOS.\n   * It also must be set to 'touch' for the fix to work.\n   */\n  -webkit-overflow-scrolling: touch;\n}\n\n.go-Container {\n  display: flex;\n  flex-direction: column;\n  flex-grow: 1;\n  height: 100%;\n  margin-bottom: 5rem;\n}\n.go-Content {\n  display: flex;\n  flex-flow: column;\n  gap: 1rem;\n  margin: 0 auto;\n  max-width: 63rem;\n  min-height: 32rem;\n  padding: 2rem var(--gutter);\n  width: 100%;\n}\n.go-Content--center {\n  justify-content: center;\n  margin: auto;\n}\n"],
-  "mappings": ";;;;;AAYA,kbAqFE,SACA,aACA,eAnGF,mBAsGE,wBAIF,8EAWE,cAEF,KACE,cAEF,MAEE,gBAEF,aAEE,YAEF,oDAIE,WACA,aAEF,MACE,yBACA,iBAGF,iBAGE,sBC3IF,KACE,wBACA,wHAEA,eACA,mBAEF,GACE,iBAEF,GACE,mBAEF,GACE,kBAEF,GACE,mBAEF,GACE,eAEF,GACE,kBAGF,YAIE,gBACA,mBACA,sBAEF,MAEE,gBACA,kBACA,sBAGF,GACE,YACA,4BAjDF,SAmDE,WAGF,EACE,eACA,mBACA,gBAEF,OACE,gBAGF,eACE,+BAEF,cACE,mBACA,gBACA,oBAEF,cACE,kBACA,gBACA,iBAEF,mBACE,kBACA,iBAEF,uBAGE,oEACA,kBACA,kBAEF,kBAEE,kDACA,qBACA,mCACA,wBACA,gBA7FF,gBA+FE,WACA,gBAGF,6BAIE,aAGF,mBAGE,iCACA,qBAEF,kBAEE,iCACA,0BC7GF,6BACE,wCACA,2CACA,mCACA,oBAGF,WACE,mBACA,qCACA,kCACA,mCACA,+BACA,eACA,oBACA,gBACA,WAEF,mCAxBA,cA4BA,qBACE,8CACA,wCAEF,yDAGE,8CACA,wCAEF,mBACE,6BAGF,qBACE,qBAGF,iBACE,mCACA,qBAEF,yBACE,gBACA,4DAEF,iBACE,qBAEF,2BACE,+CAEF,kBACE,gBACA,qBAGF,oBACE,8CACA,gBACA,wCACA,eACA,YACA,qBAEF,8BACE,uDACA,iDAEF,oFAGE,uDACA,iDAEF,4BACE,6BC9EF,kBACE,mBACA,oBAEF,kBACE,mBACA,+BACA,oBACA,kBAEF,yCACE,YAjBF,gBAoBA,+BACE,+BAEF,gCAvBA,eCMA,aACE,mBACA,aACA,sBACA,kBACA,kBAEF,mBAbA,kBAgBA,gCACE,aAEF,uBACE,OAEF,uBACE,QAEF,8CAEE,6BACA,mCACA,iBACA,eACA,qBACA,UACA,kBACA,QACA,cAEF,0DAEE,kDACA,eAEF,sLAIE,UAEF,kBACE,aACA,mBACA,UAEF,iBACE,qCAtDF,mBAwDE,gBACA,eAEF,gDAEE,0CAEF,sBACE,SACA,mBACA,gBAlEF,iBAoEE,gBApEF,UAsEE,kBACA,eCjEF,SACE,+BACA,0CARF,sBAUE,+BACA,iBAXF,wBAcA,mBACE,wCACA,mDACA,wCAEF,mBACE,wCACA,qBACA,wBAEF,sBACE,oDACA,sDACA,iCAEF,gBACE,uBACA,kCACA,iCAEF,eACE,6BACA,wCACA,iCAEF,iBACE,kDACA,yBACA,+BCpCF,cACE,kBAEF,qBACE,kDACA,mCACA,iCACA,2BACA,cACA,eACA,0BAhBF,qBAkBE,kBACA,yBACA,YACA,mBACA,aAEF,oBACE,uCACA,cACA,2DACA,oCACA,WACA,cACA,kBACA,eACA,aACA,aAEF,4JAIE,aClCF,MAEE,kBACA,kBACA,kBACA,kBACA,kBACA,kBACA,kBACA,kBACA,kBACA,mBACA,sBACA,oBACA,qBACA,gBACA,sBACA,cACA,iBACA,uBACA,gBACA,sBACA,kBACA,iBACA,cACA,kBACA,wBAGA,wCACA,iCACA,0CACA,4CACA,4CACA,uDACA,uCACA,gDACA,4CACA,8BACA,4BACA,mCACA,oCACA,mCAGA,uCACA,sCACA,iCACA,uCACA,kCACA,4CACA,iDACA,0DACA,yDACA,gEACA,uCACA,gDACA,4CACA,qDAGF,kBACE,uCACA,kCACA,2CACA,8CACA,mDACA,uCACA,0CACA,sCACA,8BACA,4BACA,mCACA,yCAEF,oCACE,gCACE,uCACA,kCACA,2CACA,8CACA,mDACA,uCACA,0CACA,sCACA,8BACA,4BACA,mCACA,0CCxFJ,WACE,kDACA,iCACA,kBACA,WAEF,iBACE,aACA,eACA,8BAfF,YAiBE,mBAjBF,6BAoBA,sBACE,gBAEF,2BACE,iCACA,aACA,OACA,kBACA,iBAEF,oCACE,mBACA,oBACA,oBACA,kBAEF,kBACE,mBACA,yBACA,aAvCF,gBAyCE,oBAEF,kBACE,oBACA,gBACA,WAEF,mBACE,aACA,OACA,eACA,gBApDF,mBAuDE,kBAEF,oBACE,mBACA,aACA,YACA,uBA7DF,8BAiEA,yDAEE,iCAGF,sBACE,oBACA,cACA,qBACA,iBAEF,yBACE,cACA,eAGF,0CACE,oBACE,aAEF,wCACE,2BChFJ,yDAEE,wCACA,2CACA,mCACA,oBACA,UAGF,mBACE,+BAGF,SACE,kBACA,aACA,sBACA,SAGF,UACE,aACA,sBACA,UAEF,kBACE,mBACA,mBAEF,iBACE,oBAEF,yBACE,WACA,gBAEF,qBAEE,8BACA,qBACA,mCACA,8BAEF,UAjDA,wBAoDA,WACE,wBACA,qBACA,gBACA,qFACA,yCACA,iCACA,mCA3DF,mDAgEA,eACE,aAEF,yBACE,OAEF,8CAtEA,gBAwEE,sBAEF,4BACE,6BACA,0BAEF,2BACE,4BACA,yBACA,sBAEF,8CAEE,UAGF,gBACE,aACA,kBAEF,0BACE,YAEF,sBACE,kBACA,kDAjGF,oBAmGE,oBACA,4BACA,sDACA,aACA,iBAvGF,mBAyGE,kBACA,aACA,kBACA,aACA,UAEF,0CACE,sBACE,iBC3GJ,sBACE,cACA,aARF,gCAWE,YAEF,oBACE,gBAdF,YAgBE,kBCVF,WACE,+BAMA,aAEF,iBACE,mBACA,aACA,8BAlBF,cAoBE,mBACA,kBACA,4BAEF,6BACE,gBAEF,kCACE,gBAEF,mBACE,mBACA,qBAEF,iDAEE,mBACA,0BACA,mBAEF,0CACE,WACE,eAIJ,WACE,mBACA,mBACA,wCACA,MACA,WACA,WAEF,iBAtDA,cAwDE,mBACA,wBAEF,6BACE,gBAEF,kCACE,kBAEF,eACE,mBACA,aACA,cACA,8BAEF,wBACE,mBACA,aACA,YACA,yBACA,WAEF,6BACE,YAEF,uBACE,mBACA,mBAEF,gBACE,cACA,YACA,qBACA,eAEF,wBACE,aAEF,oBACE,aAEF,gBACE,oBACA,aACA,YACA,gBArGF,mBAyGA,0CACE,oBACE,oBACA,oBACA,UAEF,gBACE,yBAEF,mBACE,cAGJ,yDAEE,mBACA,yCACA,sCACA,oBACA,oBA5HF,qCA+HE,kBACA,qBACA,WAEF,yEAEE,oCACA,iBAEF,4BACE,iCACA,oBAEF,6EAEE,cA9IF,4BAkJA,uGAEE,mBAGF,mBACE,4DACA,YACA,cACA,iBACA,aAEF,2BACE,aAEF,0BACE,gFACA,6HAIF,yBACE,YAEF,oBACE,aAEF,0BACE,cAEF,6CACE,aAEF,4BACE,gBACA,gBACA,iBAEF,qDACE,aAGF,0CACE,wBACE,WAEF,eACE,OAEF,oBACE,aAEF,4BACE,aAEF,wBACE,iBAIJ,qBACE,wBACA,YACA,UACA,gBACA,eACA,QACA,MACA,0BACA,qCACA,UACA,WAEF,0CACE,qBACE,cAGJ,+BACE,uBAEF,4BACE,mBACA,aACA,8BAEF,0BACE,cACA,YA1OF,YA4OE,eAEF,0BACE,gBA/OF,mBAmPA,8BACE,mBApPF,eAuPA,sCACE,6BAxPF,oBA2PA,2BACE,aACA,YACA,OACA,eACA,MACA,WACA,WAEF,0DACE,+BACA,cACA,YCjQF,SACE,YACA,eACA,2BACA,WAEF,mBACE,8GAGF,mBACE,6HAIF,mDACE,6HAGF,qCACE,4GAGF,oCACE,iEACE,6HAGF,mDACE,gHC7BJ,YACE,wBACA,kBACA,mBACA,wBACA,WAEF,oBACE,8CAEF,qBACE,iDACA,oBAEF,mBACE,+CAGF,qBACE,wBAGF,gDACE,YAEF,oCACE,8DACE,aCjCJ,OACE,kBACA,OAAS,QACT,uBACA,0BACA,kBACA,wBACA,2BACA,mBARF,YAUE,aAVF,YAYE,iBACA,WACA,cAGF,mBACE,aAGF,iBACE,eACA,MAAQ,QAAU,SAAW,OAC7B,0BAGF,iBACE,eACA,MAAQ,QAAU,SAAW,OAG/B,aACE,eACA,QACA,2BC3BF,UACE,mCACA,qBACA,mCACA,SACA,6BACA,wBACA,aACA,sBACA,SACA,gBACA,eACA,eACA,MAEF,eACE,iBAEF,iBACE,YAEF,cACE,YAEF,cACE,YAEF,iBACE,aACA,8BAEF,oBACE,kBACA,oBAEF,eACE,YACA,gBACA,gBAEF,kBACE,iBAIF,8CACE,qCACE,UACE,mBClDN,SACE,oBAEA,aACA,sBAGF,YACE,gBACA,eAEF,yBACE,sBAEF,cACE,aAEF,8CACE,cAEF,0CACE,kGAGA,gBA9BF,uBAiCA,WACE,+BACA,cACA,mBACA,gBArCF,kCAuCE,kBACA,uBACA,iBACA,mBAEF,yCAEE,cACA,eACA,gBACA,mBAjDF,eAoDA,kCAEE,0BACA,UAEF,+BACE,wBACA,gBAEF,8FAEE,kDAEF,+CACE,qBAEF,2BACE,qBACA,kBAEF,2BACE,oBAEF,2BACE,2DACA,mBACA,mBAEF,sJAEE,4CAlFF,kBAoFE,WACA,cACA,gBACA,cACA,kBACA,WACA,eAEF,wHAEE,uCACA,6CACA,eACA,oCACA,WACA,cACA,SACA,WACA,kBACA,YACA,gCACA,QAEF,4GAEE,wBAEF,4HAEE,YACA,WAEF,+CACE,qDC/GF,WANA,iBASA,cACE,aACA,SAEF,cACE,uCACA,aACA,eACA,gBAjBF,iBAoBA,4BACE,wCAEF,oBACE,wCAEF,aACE,mBACA,+BACA,oBAEF,sBACE,qBAEF,8BACE,wBC7BF,YACE,mCACA,eACA,qBACA,kBAEF,oBACE,gBAEF,wEAEE,aAEF,wBACE,2BAEF,cACE,uCACA,qBACA,mCACA,wBACA,iBACA,yBACA,iBA7BF,cA+BE,kBACA,WACA,mBACA,YACA,YCLF,MAEE,eAGA,YAGA,wGAKA,6CACA,wBACA,6CACA,gEAGF,kBACE,mDAEF,oCACE,gCACE,oDAGJ,0BACE,MACE,iBACA,YACA,yGAKJ,0BACE,MACE,gBAGJ,2BACE,MACE,kBAIJ,SACE,uCAGF,KACE,yCACA,aACA,sBACA,iBACA,kBAOA,iCAGF,cACE,aACA,sBACA,YACA,YACA,mBAEF,YACE,aACA,iBACA,SA1GF,cA4GE,gBACA,iBACA,2BACA,WAEF,oBACE,uBAlHF",
+  "sourcesContent": ["/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/*!\n * http://meyerweb.com/eric/tools/css/reset/\n * v2.0 | 20110126\n * License: none (public domain)\n */\n\nhtml,\nbody,\nbutton,\ndiv,\nspan,\napplet,\nobject,\niframe,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\ninput,\np,\nblockquote,\npre,\na,\nabbr,\nacronym,\naddress,\nbig,\ncite,\ncode,\ndel,\ndfn,\ndialog,\nem,\nimg,\nins,\nkbd,\nq,\ns,\nsamp,\nsmall,\nstrike,\nstrong,\nsub,\nsup,\ntt,\nvar,\nb,\nu,\ni,\ncenter,\ndl,\ndt,\ndd,\nol,\nul,\nli,\nfieldset,\nform,\nlabel,\nlegend,\ntable,\ncaption,\ntbody,\ntfoot,\nthead,\ntr,\nth,\ntd,\narticle,\naside,\ncanvas,\ndetails,\nembed,\nfigure,\nfigcaption,\nfooter,\nheader,\nhgroup,\nmenu,\nnav,\noutput,\nruby,\nsection,\nsummary,\ntime,\nmark,\naudio,\nvideo {\n  border: 0;\n  font: inherit;\n  font-size: 100%;\n  margin: 0;\n  padding: 0;\n  vertical-align: baseline;\n}\n\n/* HTML5 display-role reset for older browsers */\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmenu,\nnav,\nsection {\n  display: block;\n}\nbody {\n  line-height: 1;\n}\nol,\nul {\n  list-style: none;\n}\nblockquote,\nq {\n  quotes: none;\n}\nblockquote::before,\nblockquote::after,\nq::before,\nq::after {\n  content: '';\n  content: none;\n}\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\n*,\n::before,\n::after {\n  box-sizing: border-box;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nbody {\n  color: var(--color-text);\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif,\n    'Apple Color Emoji', 'Segoe UI Emoji';\n  font-size: 1rem;\n  line-height: normal;\n}\nh1 {\n  font-size: 1.5rem;\n}\nh2 {\n  font-size: 1.375rem;\n}\nh3 {\n  font-size: 1.25rem;\n}\nh4 {\n  font-size: 1.125rem;\n}\nh5 {\n  font-size: 1rem;\n}\nh6 {\n  font-size: 0.875rem;\n}\n\nh1,\nh2,\nh3,\nh4 {\n  font-weight: 600;\n  line-height: 1.25em;\n  word-break: break-word;\n}\nh5,\nh6 {\n  font-weight: 500;\n  line-height: 1.3em;\n  word-break: break-word;\n}\n\nhr {\n  border: none;\n  border-bottom: var(--border);\n  margin: 0;\n  width: 100%;\n}\n\np {\n  font-size: 1rem;\n  line-height: 1.5rem;\n  max-width: 60rem;\n}\nstrong {\n  font-weight: 600;\n}\n\n.go-textSubtle {\n  color: var(--color-text-subtle);\n}\n.go-textTitle {\n  font-size: 1.125rem;\n  font-weight: 600;\n  line-height: 1.25rem;\n}\n.go-textLabel {\n  font-size: 0.875rem;\n  font-weight: 600;\n  line-height: 1rem;\n}\n.go-textPagination {\n  font-size: 0.875rem;\n  line-height: 1rem;\n}\ncode,\npre,\ntextarea.code {\n  font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;\n  font-size: 0.875rem;\n  line-height: 1.5em;\n}\npre,\ntextarea.code {\n  background-color: var(--color-background-accented);\n  border: var(--border);\n  border-radius: var(--border-radius);\n  color: var(--color-text);\n  overflow-x: auto;\n  padding: 0.625rem;\n  tab-size: 4;\n  white-space: pre;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n  font: inherit;\n}\n\na,\na:link,\na:visited {\n  color: var(--color-brand-primary);\n  text-decoration: none;\n}\na:hover,\na:hover > * {\n  color: var(--color-brand-primary);\n  text-decoration: underline;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nbutton:focus:not([disabled]) {\n  border-color: var(--color-brand-primary);\n  -webkit-box-shadow: var(--focus-box-shadow);\n  box-shadow: var(--focus-box-shadow);\n  outline: transparent;\n}\n\n.go-Button {\n  align-items: center;\n  background-color: var(--color-button);\n  border: 0.0625rem solid transparent;\n  border-radius: var(--border-radius);\n  color: var(--color-button-text);\n  cursor: pointer;\n  display: inline-flex;\n  font-weight: 500;\n  gap: 0.25rem;\n}\n.go-Button:not(.go-Button--inline) {\n  padding: 0.5rem;\n}\n\n.go-Button--accented {\n  background-color: var(--color-button-accented);\n  color: var(--color-button-accented-text);\n}\n.go-Button--inverted,\n.go-Button--text,\n.go-Button--inline {\n  background-color: var(--color-button-inverted);\n  color: var(--color-button-inverted-text);\n}\n.go-Button--inline {\n  background-color: transparent;\n}\n\n.go-Button--inverted {\n  border: var(--border);\n}\n\n.go-Button:hover {\n  box-shadow: var(--focus-box-shadow);\n  filter: contrast(0.95);\n}\n.go-Button--inline:hover {\n  box-shadow: none;\n  text-decoration: underline var(--color-button-inverted-text);\n}\n.go-Button:focus {\n  filter: contrast(0.95);\n}\n.go-Button--inverted:focus {\n  border-color: var(--color-button-inverted-text);\n}\n.go-Button:active {\n  box-shadow: none;\n  filter: contrast(0.85);\n}\n\n.go-Button:disabled {\n  background-color: var(--color-button-disabled);\n  box-shadow: none;\n  color: var(--color-button-text-disabled);\n  cursor: initial;\n  filter: none;\n  text-decoration: none;\n}\n.go-Button--accented:disabled {\n  background-color: var(--color-button-accented-disabled);\n  color: var(--color-button-accented-text-disabled);\n}\n.go-Button--inverted:disabled,\n.go-Button--text:disabled,\n.go-Button--inline:disabled {\n  background-color: var(--color-button-inverted-disabled);\n  color: var(--color-button-inverted-text-disabled);\n}\n.go-Button--inline:disabled {\n  background-color: transparent;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Breadcrumb ol {\n  line-height: 1.5rem;\n  white-space: initial;\n}\n.go-Breadcrumb li {\n  align-items: center;\n  color: var(--color-text-subtle);\n  display: inline-flex;\n  font-size: 0.875rem;\n}\n.go-Breadcrumb li:not(:last-child)::after {\n  content: '>';\n  padding: 0 0.5rem;\n}\n.go-Breadcrumb li:last-child > a {\n  color: var(--color-text-subtle);\n}\n.go-Breadcrumb li > .go-Clipboard {\n  margin: 0 0.5rem;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Carousel {\n  align-items: center;\n  display: flex;\n  flex-direction: column;\n  position: relative;\n  text-align: center;\n}\n.go-Carousel-slide {\n  margin: 0.5rem 3rem;\n}\n.go-Carousel-slide[aria-hidden] {\n  display: none;\n}\n.go-Carousel-prevSlide {\n  left: 0;\n}\n.go-Carousel-nextSlide {\n  right: 0;\n}\n.go-Carousel-prevSlide,\n.go-Carousel-nextSlide {\n  background-color: transparent;\n  border-radius: var(--border-radius);\n  font-size: 1.5rem;\n  height: 2.75rem;\n  margin-top: -1.375rem;\n  opacity: 0;\n  position: absolute;\n  top: 50%;\n  width: 2.75rem;\n}\n.go-Carousel-prevSlide:hover,\n.go-Carousel-nextSlide:hover {\n  background-color: var(--color-background-accented);\n  cursor: pointer;\n}\n.go-Carousel:hover .go-Carousel-prevSlide,\n.go-Carousel:hover .go-Carousel-nextSlide,\n.go-Carousel:focus-within .go-Carousel-prevSlide,\n.go-Carousel:focus-within .go-Carousel-nextSlide {\n  opacity: 1;\n}\n.go-Carousel-dots {\n  display: flex;\n  font-size: 0.4375rem;\n  gap: 0.5rem;\n}\n.go-Carousel-dot {\n  background-color: var(--color-border);\n  border-radius: 2rem;\n  height: 0.4375rem;\n  width: 0.4375rem;\n}\n.go-Carousel-dot--active,\n.go-Carousel-dot:hover {\n  background-color: var(--color-text-subtle);\n}\n.go-Carousel-obscured {\n  border: 0;\n  clip: rect(0 0 0 0);\n  height: 0.0625rem;\n  margin: -0.0625rem;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 0.0625rem;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Chip {\n  background: var(--color-button);\n  border: 0.0625rem solid var(--color-button);\n  border-radius: 1.25rem;\n  color: var(--color-button-text);\n  font-size: 0.75rem;\n  padding: 0.125rem 0.625rem;\n}\n.go-Chip--accented {\n  background: var(--color-button-accented);\n  border: 0.0625rem solid var(--color-button-accented);\n  color: var(--color-button-accented-text);\n}\n.go-Chip--inverted {\n  background: var(--color-button-inverted);\n  border: var(--border);\n  color: var(--color-text);\n}\n.go-Chip--highlighted {\n  background: var(--color-background-highlighted-link);\n  border-color: var(--color-background-highlighted-link);\n  color: var(--color-brand-primary);\n}\n.go-Chip--alert {\n  background: var(--pink);\n  border: 0.0625rem solid var(--pink);\n  color: var(--color-text-inverted);\n}\n.go-Chip--vuln {\n  background: var(--pink-light);\n  border: 0.0625rem solid var(--pink-light);\n  color: var(--color-text-inverted);\n}\n.go-Chip--subtle {\n  background-color: var(--color-background-accented);\n  border-color: transparent;\n  color: var(--color-text-subtle);\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Clipboard {\n  position: relative;\n}\n.go-Clipboard::before {\n  background-color: var(--color-background-inverted);\n  border-radius: var(--border-radius);\n  color: var(--color-text-inverted);\n  content: attr(data-tooltip);\n  display: block;\n  font-size: 0.9em;\n  left: calc(100% + 0.125rem);\n  padding: 0.25rem 0.3rem;\n  position: absolute;\n  text-transform: uppercase;\n  top: 0.125rem;\n  white-space: nowrap;\n  z-index: 1000;\n}\n.go-Clipboard::after {\n  border-bottom: 0.25rem solid transparent;\n  border-left: 0;\n  border-right: 0.25rem solid var(--color-background-inverted);\n  border-top: 0.25rem solid transparent;\n  content: '';\n  display: block;\n  position: absolute;\n  right: -0.125rem;\n  top: 0.5625rem;\n  z-index: 1000;\n}\n.go-Clipboard:not([data-tooltip])::before,\n.go-Clipboard:not([data-tooltip])::after,\n.go-Clipboard[data-tooltip='']::before,\n.go-Clipboard[data-tooltip='']::after {\n  display: none;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n:root {\n  /* Colors */\n  --gray-1: #202224;\n  --gray-2: #3e4042;\n  --gray-3: #555759;\n  --gray-4: #6e7072;\n  --gray-5: #848688;\n  --gray-6: #aaacae;\n  --gray-7: #c6c8ca;\n  --gray-8: #dcdee0;\n  --gray-9: #f0f1f2;\n  --gray-10: #f8f8f8;\n  --turq-light: #5dc9e2;\n  --turq-med: #50b7e0;\n  --turq-dark: #007d9c;\n  --blue: #bfeaf4;\n  --blue-light: #f2fafd;\n  --black: #000;\n  --green: #3a6e11;\n  --green-light: #5fda64;\n  --pink: #ce3262;\n  --pink-light: #fdecf1;\n  --purple: #542c7d;\n  --slate: #253443; /* Footer background. */\n  --white: #fff;\n  --yellow: #fddd00;\n  --yellow-light: #fff8cc;\n\n  /* Color Intents */\n  --color-brand-primary: var(--turq-dark);\n  --color-background: var(--white);\n  --color-background-inverted: var(--slate);\n  --color-background-accented: var(--gray-10);\n  --color-background-highlighted: var(--blue);\n  --color-background-highlighted-link: var(--blue-light);\n  --color-background-info: var(--gray-9);\n  --color-background-warning: var(--yellow-light);\n  --color-background-alert: var(--pink-light);\n  --color-border: var(--gray-7);\n  --color-text: var(--gray-1);\n  --color-text-subtle: var(--gray-4);\n  --color-text-inverted: var(--white);\n  --color-code-comment: var(--green);\n\n  /* Interactive Colors */\n  --color-input: var(--color-background);\n  --color-input-text: var(--color-text);\n  --color-button: var(--turq-dark);\n  --color-button-disabled: var(--gray-9);\n  --color-button-text: var(--white);\n  --color-button-text-disabled: var(--gray-3);\n  --color-button-inverted: var(--color-background);\n  --color-button-inverted-disabled: var(--color-background);\n  --color-button-inverted-text: var(--color-brand-primary);\n  --color-button-inverted-text-disabled: var(--color-text-subtle);\n  --color-button-accented: var(--yellow);\n  --color-button-accented-disabled: var(--gray-9);\n  --color-button-accented-text: var(--gray-1);\n  --color-button-accented-text-disabled: var(--gray-3);\n}\n\n[data-theme='dark'] {\n  --color-brand-primary: var(--turq-med);\n  --color-background: var(--gray-1);\n  --color-background-accented: var(--gray-2);\n  --color-background-highlighted: var(--gray-2);\n  --color-background-highlighted-link: var(--gray-2);\n  --color-background-info: var(--gray-3);\n  --color-background-warning: var(--yellow);\n  --color-background-alert: var(--pink);\n  --color-border: var(--gray-4);\n  --color-text: var(--gray-9);\n  --color-text-subtle: var(--gray-7);\n  --color-code-comment: var(--green-light);\n}\n@media (prefers-color-scheme: dark) {\n  :root:not([data-theme='light']) {\n    --color-brand-primary: var(--turq-med);\n    --color-background: var(--gray-1);\n    --color-background-accented: var(--gray-2);\n    --color-background-highlighted: var(--gray-2);\n    --color-background-highlighted-link: var(--gray-2);\n    --color-background-info: var(--gray-3);\n    --color-background-warning: var(--yellow);\n    --color-background-alert: var(--pink);\n    --color-border: var(--gray-4);\n    --color-text: var(--gray-9);\n    --color-text-subtle: var(--gray-7);\n    --color-code-comment: var(--green-light);\n  }\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Footer {\n  background-color: var(--color-background-inverted);\n  color: var(--color-text-inverted);\n  font-size: 0.875rem;\n  width: 100%;\n}\n.go-Footer-links {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: space-between;\n  margin: auto;\n  max-width: 75.75rem;\n  padding: 2rem 1.5rem 2.625rem 1.5rem;\n}\n.go-Footer-linkColumn {\n  flex: 0 0 9.5rem;\n}\n.go-Footer .go-Footer-link {\n  color: var(--color-text-inverted);\n  display: flex;\n  flex: 1;\n  font-size: 0.875rem;\n  line-height: 2rem;\n}\n.go-Footer .go-Footer-link--primary {\n  font-size: 1.125rem;\n  line-height: 1.75rem;\n  margin-bottom: 0.5rem;\n  margin-top: 0.75rem;\n}\n.go-Footer-bottom {\n  align-items: center;\n  border-top: var(--border);\n  display: flex;\n  margin: 0 1.5rem;\n  min-height: 4.125rem;\n}\n.go-Footer-gopher {\n  align-self: flex-end;\n  height: 3.147rem;\n  width: 5rem;\n}\n.go-Footer-listRow {\n  display: flex;\n  flex: 1;\n  flex-wrap: wrap;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  text-align: center;\n}\n.go-Footer-listItem {\n  align-items: center;\n  display: flex;\n  flex: 1 100%;\n  justify-content: center;\n  margin: 0.4rem 0;\n  padding: 0 1rem;\n}\n.go-Footer-listItem a:link,\n.go-Footer-listItem a:visited {\n  color: var(--color-text-inverted);\n}\n.go-Footer-listItem .go-Button--text {\n  background-color: transparent;\n  font-size: 1rem;\n}\n.go-Footer-listItem [data-value] {\n  display: none;\n}\n\n[data-theme='auto'] .go-Footer-listItem [data-value='auto'],\n:root:not([data-theme]) .go-Footer-listItem [data-value='auto'] {\n  display: initial;\n}\n[data-theme='dark'] .go-Footer-listItem [data-value='dark'] {\n  display: initial;\n}\n[data-theme='light'] .go-Footer-listItem [data-value='light'] {\n  display: initial;\n}\n.go-Footer-toggleTheme,\n.go-Footer-keyboard {\n  margin: 0 0 0.5rem 0;\n}\n\n.go-Footer-googleLogo {\n  align-self: flex-end;\n  height: 1.5rem;\n  margin-bottom: 1.3rem;\n  text-align: right;\n}\n.go-Footer-googleLogoImg {\n  height: 1.5rem;\n  width: 4.529rem;\n}\n\n@media only screen and (min-width: 52rem) {\n  .go-Footer-listItem {\n    flex: initial;\n  }\n  .go-Footer-listItem + .go-Footer-listItem {\n    border-left: var(--border);\n  }\n  .go-Footer-toggleTheme {\n    margin: 0 0 0 -0.5rem;\n  }\n  .go-Footer-keyboard {\n    margin: 0;\n  }\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nselect:focus:not([disabled]),\ninput:focus:not([disabled]) {\n  border-color: var(--color-brand-primary);\n  -webkit-box-shadow: var(--focus-box-shadow);\n  box-shadow: var(--focus-box-shadow);\n  outline: transparent;\n  z-index: 2;\n}\n\ninput::placeholder {\n  color: var(--color-text-subtle);\n}\n\n.go-Form {\n  align-items: start;\n  display: flex;\n  flex-direction: column;\n  gap: 1rem;\n}\n\n.go-Label {\n  display: flex;\n  flex-direction: column;\n  gap: 0.5rem;\n}\n.go-Label--inline {\n  align-items: center;\n  flex-direction: row;\n}\n.go-Label legend {\n  margin-bottom: 0.5rem;\n}\n.go-Label--inline legend {\n  float: left;\n  margin-bottom: 0;\n}\n.go-Input,\n.go-Select {\n  background: var(--color-input);\n  border: var(--border);\n  border-radius: var(--border-radius);\n  color: var(--color-input-text);\n}\n.go-Input {\n  padding: 0.40625rem 0.5rem;\n}\n.go-Select {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  background: url('/static/shared/icon/arrow_drop_down_gm_grey_24dp.svg') right no-repeat;\n  background-color: var(--color-background);\n  background-position: right center;\n  border-radius: var(--border-radius);\n  margin: 0;\n  padding: 0.34375rem 1.25rem 0.34375rem 0.5rem;\n}\n\n.go-InputGroup {\n  display: flex;\n}\n.go-InputGroup .go-Input {\n  flex: 1;\n}\n.go-InputGroup > :not(:first-child, :last-child) {\n  border-radius: 0;\n  margin-left: -0.0625rem;\n}\n.go-InputGroup > :first-child {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.go-InputGroup > :last-child {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n  margin-left: -0.0625rem;\n}\n.go-InputGroup > *:hover,\n.go-InputGroup > *:focus {\n  z-index: 1;\n}\n\n.go-ShortcutKey {\n  display: flex;\n  position: relative;\n}\n.go-ShortcutKey .go-Input {\n  flex-grow: 1;\n}\n.go-ShortcutKey::after {\n  align-self: center;\n  background-color: var(--color-background-accented);\n  border-radius: 0.5rem;\n  color: var(--gray-6);\n  content: attr(data-shortcut);\n  content: attr(data-shortcut) / attr(data-shortcut-alt);\n  display: none;\n  font-size: 0.75rem;\n  padding: 0.0625rem 0;\n  position: absolute;\n  right: 0.75rem;\n  text-align: center;\n  width: 1.5rem;\n  z-index: 1;\n}\n@media only screen and (min-width: 52rem) {\n  .go-ShortcutKey::after {\n    display: initial;\n  }\n}\n", "/*!\n * Copyright 2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-GopherMessage img {\n  display: block;\n  height: 15rem;\n  margin: 0 auto;\n  padding: 1.25rem 0;\n  width: 15rem;\n}\n.go-GopherMessage p {\n  font-weight: 600;\n  margin: auto;\n  text-align: center;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Banner {\n  background-color: var(--gray-1);\n\n  /**\n   * Only show on wide viewports so the\n   * text never wraps or gets cut off.\n   */\n  display: none;\n}\n.go-Banner-inner {\n  align-items: center;\n  display: flex;\n  justify-content: space-between;\n  margin: 0 auto;\n  max-width: 75.75rem;\n  min-height: 2.5rem;\n  padding: 0.5rem var(--gutter);\n}\n.Site--wide .go-Banner-inner {\n  max-width: 98rem;\n}\n.go-Banner--full .go-Banner-inner {\n  max-width: unset;\n}\n.go-Banner-message {\n  color: var(--white);\n  margin-right: 1.25rem;\n}\n.go-Banner-action:link,\n.go-Banner-action:visited {\n  color: var(--white);\n  text-decoration: underline;\n  white-space: nowrap;\n}\n@media only screen and (min-width: 52rem) {\n  .go-Banner {\n    display: block;\n  }\n}\n\n.go-Header {\n  background: #007d9c;\n  border-bottom: none;\n  box-shadow: 0 0.0625rem 0.125rem rgba(171, 171, 171, 0.3);\n  top: 0;\n  width: 100%;\n  z-index: 10;\n}\n.go-Header-inner {\n  margin: 0 auto;\n  max-width: 75.75rem;\n  padding: 0 var(--gutter);\n}\n.Site--wide .go-Header-inner {\n  max-width: 98rem;\n}\n.go-Header--full .go-Header-inner {\n  max-width: initial;\n}\n.go-Header-nav {\n  align-items: center;\n  display: flex;\n  height: 3.5rem;\n  justify-content: space-between;\n}\n.go-Header-rightContent {\n  align-items: center;\n  display: flex;\n  height: 100%;\n  justify-content: flex-end;\n  width: 100%;\n}\n.go-Header-rightContent form {\n  flex-grow: 1;\n}\n.go-Header-inner--dark {\n  border-bottom: none;\n  color: var(--white);\n}\n.go-Header-logo {\n  display: block;\n  height: 2rem;\n  margin-right: 2.25rem;\n  width: 5.125rem;\n}\n.go-Header-logo--hidden {\n  display: none;\n}\n.go-Header-menuItem {\n  display: none;\n}\n.go-Header-menu {\n  align-items: stretch;\n  display: flex;\n  height: 100%;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n@media only screen and (min-width: 65rem) {\n  .go-Header-menuItem {\n    align-items: stretch;\n    display: inline-flex;\n    flex: none;\n  }\n  .go-Header-menu {\n    justify-content: flex-end;\n  }\n  .go-Header-navOpen {\n    display: none;\n  }\n}\n.go-Header-menuItem a:link,\n.go-Header-menuItem a:visited {\n  align-items: center;\n  border-bottom: 0.1875rem solid transparent;\n  border-top: 0.1875rem solid transparent; /* To ensure the text remains centered. */\n  color: var(--gray-2);\n  display: inline-flex;\n  margin: 0 0.3125rem;\n  padding: 0 0.9375rem;\n  text-align: center;\n  text-decoration: none;\n  width: 100%;\n}\n.go-Header-menuItem--active a:link,\n.go-Header-menuItem--active a:visited {\n  border-bottom-color: var(--turq-med);\n  font-weight: bold;\n}\n.go-Header-menuItem a:hover {\n  border-bottom-color: var(--white);\n  color: var(--gray-2);\n}\n.go-NavigationDrawer-listItem a:link,\n.go-NavigationDrawer-listItem a:visited {\n  display: block;\n  margin: 0 1rem;\n  padding: 0.5rem;\n}\n.go-Header-inner--dark .go-Header-menuItem a:link,\n.go-Header-inner--dark .go-Header-menuItem a:visited {\n  color: var(--white);\n}\n\n.go-Header-navOpen {\n  background: no-repeat center/2rem url('/images/menu-24px.svg');\n  border: none;\n  height: 2.5rem;\n  margin-left: 1rem;\n  width: 2.5rem;\n}\n.go-Header-navOpen--hidden {\n  display: none;\n}\n.go-Header-navOpen--white {\n  background: no-repeat center/2rem url('/static/shared/icon/menu_gm_grey_24dp.svg');\n  filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg)\n    brightness(103%) contrast(107%);\n}\n\n.go-SearchForm--expanded {\n  flex-grow: 1;\n}\n.go-SearchForm-form {\n  display: none;\n}\n.go-SearchForm-form::after {\n  right: 2.75rem;\n}\n.go-SearchForm--expanded .go-SearchForm-form {\n  display: flex;\n}\n.go-SearchForm-expandSearch {\n  appearance: none;\n  background: none;\n  font-size: 1.5rem;\n}\n.go-SearchForm--expanded .go-SearchForm-expandSearch {\n  display: none;\n}\n\n@media only screen and (min-width: 32rem) {\n  .go-Header-rightContent {\n    width: 100%;\n  }\n  .go-SearchForm {\n    flex: 1;\n  }\n  .go-SearchForm-form {\n    display: flex;\n  }\n  .go-SearchForm-expandSearch {\n    display: none;\n  }\n  .go-Header-logo--hidden {\n    display: initial;\n  }\n}\n\n.go-NavigationDrawer {\n  background: var(--white);\n  height: 100%;\n  left: auto;\n  max-width: 27rem;\n  position: fixed;\n  right: 0;\n  top: 0;\n  transform: translateX(100%);\n  transition: transform 100ms ease-in-out;\n  width: 85%;\n  z-index: 30;\n}\n@media only screen and (min-width: 65rem) {\n  .go-NavigationDrawer {\n    display: none;\n  }\n}\n.go-NavigationDrawer.is-active {\n  transform: translateX(0);\n}\n.go-NavigationDrawer-header {\n  align-items: center;\n  display: flex;\n  justify-content: space-between;\n}\n.go-NavigationDrawer-logo {\n  display: block;\n  height: 2rem;\n  margin: 1rem 1rem;\n  width: 5.125rem;\n}\n.go-NavigationDrawer-list {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n.go-NavigationDrawer-listItem {\n  font-size: 1.125rem;\n  margin: 0 0.5rem;\n}\n.go-NavigationDrawer-listItem--active {\n  background-color: var(--blue);\n  border-radius: 0.4rem;\n}\n.go-NavigationDrawer-scrim {\n  display: none;\n  height: 100%;\n  left: 0;\n  position: fixed;\n  top: 0;\n  width: 100%;\n  z-index: 20;\n}\n.go-NavigationDrawer.is-active + .go-NavigationDrawer-scrim {\n  background-color: var(--gray-1);\n  display: block;\n  opacity: 0.32;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Icon {\n  filter: none;\n  height: 1.125em;\n  vertical-align: text-bottom;\n  width: auto;\n}\n.go-Icon--accented {\n  filter: brightness(0) invert(45%) sepia(94%) saturate(6735%) hue-rotate(176deg) brightness(94%)\n    contrast(101%);\n}\n.go-Icon--inverted {\n  filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg)\n    brightness(103%) contrast(107%);\n}\n\n[data-theme='dark'] .go-Icon:not(.go-Icon--accented) {\n  filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg)\n    brightness(103%) contrast(107%);\n}\n[data-theme='dark'] .go-Icon--accented {\n  filter: brightness(0) invert(69%) sepia(46%) saturate(466%) hue-rotate(153deg) brightness(90%)\n    contrast(88%);\n}\n@media (prefers-color-scheme: dark) {\n  :root:not([data-theme='light']) .go-Icon:not(.go-Icon--accented) {\n    filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg)\n      brightness(103%) contrast(107%);\n  }\n  :root:not([data-theme='light']) .go-Icon--accented {\n    filter: brightness(0) invert(57%) sepia(63%) saturate(4864%) hue-rotate(160deg) brightness(100%)\n      contrast(101%);\n  }\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Message {\n  color: var(--color-text);\n  font-size: 0.875rem;\n  line-height: 1.5rem;\n  padding: 0 var(--gutter);\n  width: 100%;\n}\n.go-Message--notice {\n  background-color: var(--color-background-info);\n}\n.go-Message--warning {\n  background-color: var(--color-background-warning);\n  color: var(--gray-1);\n}\n.go-Message--alert {\n  background-color: var(--color-background-alert);\n}\n\n.go-Message > .go-Icon {\n  vertical-align: text-top;\n}\n\n[data-theme='dark'] .go-Message--warning .go-Icon {\n  filter: none;\n}\n@media (prefers-color-scheme: dark) {\n  :root:not([data-theme='light']) .go-Message--warning .go-Icon {\n    filter: none;\n  }\n}\n", "dialog {\n  position: absolute;\n  left: 0; right: 0;\n  width: -moz-fit-content;\n  width: -webkit-fit-content;\n  width: fit-content;\n  height: -moz-fit-content;\n  height: -webkit-fit-content;\n  height: fit-content;\n  margin: auto;\n  border: solid;\n  padding: 1em;\n  background: white;\n  color: black;\n  display: block;\n}\n\ndialog:not([open]) {\n  display: none;\n}\n\ndialog + .backdrop {\n  position: fixed;\n  top: 0; right: 0; bottom: 0; left: 0;\n  background: rgba(0,0,0,0.1);\n}\n\n._dialog_overlay {\n  position: fixed;\n  top: 0; right: 0; bottom: 0; left: 0;\n}\n\ndialog.fixed {\n  position: fixed;\n  top: 50%;\n  transform: translate(0, -50%);\n}", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n@import url('../../../third_party/dialog-polyfill/dialog-polyfill.css');\n\n.go-Modal {\n  background: var(--color-background);\n  border: var(--border);\n  border-radius: var(--border-radius);\n  bottom: 0;\n  box-shadow: var(--box-shadow);\n  color: var(--color-text);\n  display: flex;\n  flex-direction: column;\n  gap: 1rem;\n  max-height: 100%;\n  max-width: 100%;\n  position: fixed;\n  top: 0;\n}\n.go-Modal > form {\n  display: contents;\n}\n.go-Modal--small {\n  width: 20rem;\n}\n.go-Modal--md {\n  width: 30rem;\n}\n.go-Modal--lg {\n  width: 40rem;\n}\n.go-Modal-header {\n  display: flex;\n  justify-content: space-between;\n}\n.go-Modal-header h2 {\n  font-size: 1.15rem;\n  line-height: 1.25rem;\n}\n.go-Modal-body {\n  flex-grow: 1;\n  min-height: 2rem;\n  min-width: 18rem;\n}\n.go-Modal-actions {\n  text-align: right;\n}\n\n/* Safari only */\n@media not all and (min-resolution: 0.001dpcm) {\n  @supports (-webkit-appearance: none) {\n    .go-Modal {\n      padding-bottom: 0;\n    }\n  }\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Tree {\n  --js-tree-height: 0;\n\n  display: flex;\n  flex-direction: column;\n}\n\n.go-Tree ul {\n  list-style: none;\n  padding-left: 0;\n}\n.go-Tree li:last-of-type {\n  padding-bottom: 0.25rem;\n}\n.go-Tree a + ul {\n  display: none;\n}\n.go-Tree a[aria-expanded='true'] + ul[role='group'] {\n  display: block;\n}\n.go-Tree a[aria-level='1'] + ul[role='group'] {\n  max-height: calc(\n    100vh - var(--js-tree-height, 0) - var(--js-sticky-header-height, 3.5rem) - 5rem\n  );\n  overflow-y: auto;\n  padding: 0.5rem 0.25rem 0 0.25rem;\n}\n.go-Tree a {\n  color: var(--color-text-subtle);\n  display: block;\n  line-height: 1.5rem;\n  overflow: hidden;\n  padding: 0.125rem 0 0.125rem 1.25rem;\n  position: relative;\n  text-overflow: ellipsis;\n  user-select: none;\n  white-space: nowrap;\n}\n.go-Tree > li > a,\n.go-Tree a[aria-level='1'] {\n  display: block;\n  font-size: 1rem;\n  font-weight: 500;\n  line-height: 2.5rem;\n  padding: 0 1rem;\n}\n.go-Tree a:focus,\n.go-Tree a:hover {\n  text-decoration: underline;\n  z-index: 1;\n}\n.go-Tree a[aria-selected='true'] {\n  color: var(--color-text);\n  font-weight: 500;\n}\n.go-Tree a[aria-level='1'][aria-selected='true'],\n.go-Tree a[aria-level='1'][aria-expanded='true'] {\n  background-color: var(--color-background-accented);\n}\n.go-Tree a[aria-level='3'][aria-expanded='true'] {\n  margin-bottom: 0.375em;\n}\n.go-Tree a[aria-level='2'] {\n  margin-bottom: 0.25rem;\n  position: relative;\n}\n.go-Tree a[aria-level='3'] {\n  padding-left: 2.5rem;\n}\n.go-Tree a[aria-level='4'] {\n  border-left: 0.125rem solid var(--color-background-accented);\n  margin-left: 2.5rem;\n  padding-left: 0.5rem;\n}\n.go-Tree a[aria-selected='true'][aria-level='2']:not([aria-expanded])::before,\n.go-Tree a[aria-selected='true'][aria-level='3']:not([aria-expanded])::before {\n  background-color: var(--color-brand-primary);\n  border-radius: 50%;\n  content: '';\n  display: block;\n  height: 0.3125rem;\n  left: 0.4688rem;\n  position: absolute;\n  top: 0.75rem;\n  width: 0.3125rem;\n}\n.go-Tree a[aria-expanded][aria-owns][aria-level='2']::before,\n.go-Tree a[aria-expanded][aria-owns][aria-level='3']::before {\n  border-bottom: 0.25rem solid transparent;\n  border-left: 0.25rem solid var(--color-border);\n  border-right: 0;\n  border-top: 0.25rem solid transparent;\n  content: '';\n  display: block;\n  height: 0;\n  left: 0.5rem;\n  position: absolute;\n  top: 0.625rem;\n  transition: transform 0.1s linear;\n  width: 0;\n}\n.go-Tree a[aria-expanded='true'][aria-level='2']::before,\n.go-Tree a[aria-expanded='true'][aria-level='3']::before {\n  transform: rotate(90deg);\n}\n.go-Tree a[aria-expanded][aria-level='3']:not([empty])::before,\n.go-Tree a[aria-selected][aria-level='3']:not([empty])::before {\n  left: 1.5rem;\n  top: 0.75rem;\n}\n.go-Tree a[aria-selected='true'][aria-level='4'] {\n  border-left: 0.125rem solid var(--color-brand-primary);\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-TabNav {\n  margin: 0 0 0.5rem 0;\n}\n.go-TabNav ul {\n  display: flex;\n  gap: 2rem;\n}\n.go-TabNav li {\n  border-bottom: 0.25rem transparent solid;\n  display: flex;\n  font-size: 1rem;\n  height: 2.375rem;\n  padding: 0 0.25rem;\n}\n.go-TabNav li[aria-current] {\n  border-color: var(--color-brand-primary);\n}\n.go-TabNav li:hover {\n  border-color: var(--color-brand-primary);\n}\n.go-TabNav a {\n  align-items: center;\n  color: var(--color-text-subtle);\n  display: inline-flex;\n}\n.go-TabNav li:hover a {\n  text-decoration: none;\n}\n.go-TabNav li[aria-current] a {\n  color: var(--color-text);\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n.go-Tooltip {\n  border-radius: var(--border-radius);\n  cursor: pointer;\n  display: inline-block;\n  position: relative;\n}\n.go-Tooltip > summary {\n  list-style: none;\n}\n.go-Tooltip > summary::-webkit-details-marker,\n.go-Tooltip > summary::marker {\n  display: none;\n}\n.go-Tooltip > summary > img {\n  vertical-align: text-bottom;\n}\n.go-Tooltip p {\n  background: var(--color-background) 80%;\n  border: var(--border);\n  border-radius: var(--border-radius);\n  color: var(--color-text);\n  font-size: 0.75rem;\n  letter-spacing: 0.01875rem;\n  line-height: 1rem;\n  padding: 0.5rem;\n  position: absolute;\n  top: 1.5rem;\n  white-space: normal;\n  width: 12rem;\n  z-index: 100;\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n@import url('./reset.css');\n\n/**\n * Typography should be imported first in the list below to ensure expected\n * CSS rule inheritance on text elements.\n */\n@import url('./typography/typography.css');\n@import url('./button/button.css');\n@import url('./breadcrumb/breadcrumb.css');\n@import url('./carousel/carousel.css');\n@import url('./chip/chip.css');\n@import url('./clipboard/clipboard.css');\n@import url('./color/color.css');\n@import url('./footer/footer.css');\n@import url('./form/form.css');\n@import url('./gopher/gopher.css');\n@import url('./header/header.css');\n@import url('./icon/icon.css');\n@import url('./message/message.css');\n@import url('./modal/modal.css');\n@import url('./outline/tree.css');\n@import url('./tabnav/tabnav.css');\n@import url('./tooltip/tooltip.css');\n\n:root {\n  /* Padding at the left and right of the viewport. */\n  --gutter: 1rem;\n\n  /* Margin between containers in the grid layout. */\n  --gap: 1rem;\n\n  /* The margin placed above elements scrolled to by clicking hash links. */\n  --scroll-margin: calc(\n    var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 2rem\n  );\n\n  /* Default styles for page elements. */\n  --border: 0.0625rem solid var(--color-border);\n  --border-radius: 0.25rem;\n  --box-shadow: 0 0 0.375rem 0 rgb(0 0 0 / 25%);\n  --focus-box-shadow: 0 0 0.0625rem 0.0625rem rgba(0, 112, 210, 0.6);\n}\n\n[data-theme='dark'] {\n  --box-shadow: 0 0.3125rem 0.9375rem rgb(0 0 0 / 45%);\n}\n@media (prefers-color-scheme: dark) {\n  :root:not([data-theme='light']) {\n    --box-shadow: 0 0.3125rem 0.9375rem rgb(0 0 0 / 45%);\n  }\n}\n@media (min-width: 50rem) {\n  :root {\n    --gutter: 1.5rem;\n    --gap: 2rem;\n    --scroll-margin: calc(\n      var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 1rem\n    );\n  }\n}\n@media (min-width: 80rem) {\n  :root {\n    --gutter: 2rem;\n  }\n}\n@media (min-width: 112rem) {\n  :root {\n    --gutter: 2.5rem;\n  }\n}\n\n*:target {\n  scroll-margin-top: var(--scroll-margin);\n}\n\nbody {\n  background-color: var(--color-background);\n  display: flex;\n  flex-direction: column;\n  min-height: 100vh;\n  min-width: 23.5rem;\n\n  /**\n   * This is used to programatically detect whether overflow needs to be altered\n   * to prevent jitter when focusing within fixed elements on iOS.\n   * It also must be set to 'touch' for the fix to work.\n   */\n  -webkit-overflow-scrolling: touch;\n}\n\n.go-Container {\n  display: flex;\n  flex-direction: column;\n  flex-grow: 1;\n  height: 100%;\n  margin-bottom: 5rem;\n}\n.go-Content {\n  display: flex;\n  flex-flow: column;\n  gap: 1rem;\n  margin: 0 auto;\n  max-width: 63rem;\n  min-height: 32rem;\n  padding: 2rem var(--gutter);\n  width: 100%;\n}\n.go-Content--center {\n  justify-content: center;\n  margin: auto;\n}\n"],
+  "mappings": ";;;;;AAYA,kbAqFE,SACA,aACA,eAnGF,mBAsGE,wBAIF,8EAWE,cAEF,KACE,cAEF,MAEE,gBAEF,aAEE,YAEF,oDAIE,WACA,aAEF,MACE,yBACA,iBAGF,iBAGE,sBC3IF,KACE,wBACA,wHAEA,eACA,mBAEF,GACE,iBAEF,GACE,mBAEF,GACE,kBAEF,GACE,mBAEF,GACE,eAEF,GACE,kBAGF,YAIE,gBACA,mBACA,sBAEF,MAEE,gBACA,kBACA,sBAGF,GACE,YACA,4BAjDF,SAmDE,WAGF,EACE,eACA,mBACA,gBAEF,OACE,gBAGF,eACE,+BAEF,cACE,mBACA,gBACA,oBAEF,cACE,kBACA,gBACA,iBAEF,mBACE,kBACA,iBAEF,uBAGE,oEACA,kBACA,kBAEF,kBAEE,kDACA,qBACA,mCACA,wBACA,gBA7FF,gBA+FE,WACA,gBAGF,6BAIE,aAGF,mBAGE,iCACA,qBAEF,kBAEE,iCACA,0BC7GF,6BACE,wCACA,2CACA,mCACA,oBAGF,WACE,mBACA,qCACA,kCACA,mCACA,+BACA,eACA,oBACA,gBACA,WAEF,mCAxBA,cA4BA,qBACE,8CACA,wCAEF,yDAGE,8CACA,wCAEF,mBACE,6BAGF,qBACE,qBAGF,iBACE,mCACA,qBAEF,yBACE,gBACA,4DAEF,iBACE,qBAEF,2BACE,+CAEF,kBACE,gBACA,qBAGF,oBACE,8CACA,gBACA,wCACA,eACA,YACA,qBAEF,8BACE,uDACA,iDAEF,oFAGE,uDACA,iDAEF,4BACE,6BC9EF,kBACE,mBACA,oBAEF,kBACE,mBACA,+BACA,oBACA,kBAEF,yCACE,YAjBF,gBAoBA,+BACE,+BAEF,gCAvBA,eCMA,aACE,mBACA,aACA,sBACA,kBACA,kBAEF,mBAbA,kBAgBA,gCACE,aAEF,uBACE,OAEF,uBACE,QAEF,8CAEE,6BACA,mCACA,iBACA,eACA,qBACA,UACA,kBACA,QACA,cAEF,0DAEE,kDACA,eAEF,sLAIE,UAEF,kBACE,aACA,mBACA,UAEF,iBACE,qCAtDF,mBAwDE,gBACA,eAEF,gDAEE,0CAEF,sBACE,SACA,mBACA,gBAlEF,iBAoEE,gBApEF,UAsEE,kBACA,eCjEF,SACE,+BACA,0CARF,sBAUE,+BACA,iBAXF,wBAcA,mBACE,wCACA,mDACA,wCAEF,mBACE,wCACA,qBACA,wBAEF,sBACE,oDACA,sDACA,iCAEF,gBACE,uBACA,kCACA,iCAEF,eACE,6BACA,wCACA,iCAEF,iBACE,kDACA,yBACA,+BCpCF,cACE,kBAEF,qBACE,kDACA,mCACA,iCACA,2BACA,cACA,eACA,0BAhBF,qBAkBE,kBACA,yBACA,YACA,mBACA,aAEF,oBACE,uCACA,cACA,2DACA,oCACA,WACA,cACA,kBACA,eACA,aACA,aAEF,4JAIE,aClCF,MAEE,kBACA,kBACA,kBACA,kBACA,kBACA,kBACA,kBACA,kBACA,kBACA,mBACA,sBACA,oBACA,qBACA,gBACA,sBACA,cACA,iBACA,uBACA,gBACA,sBACA,kBACA,iBACA,cACA,kBACA,wBAGA,wCACA,iCACA,0CACA,4CACA,4CACA,uDACA,uCACA,gDACA,4CACA,8BACA,4BACA,mCACA,oCACA,mCAGA,uCACA,sCACA,iCACA,uCACA,kCACA,4CACA,iDACA,0DACA,yDACA,gEACA,uCACA,gDACA,4CACA,qDAGF,kBACE,uCACA,kCACA,2CACA,8CACA,mDACA,uCACA,0CACA,sCACA,8BACA,4BACA,mCACA,yCAEF,oCACE,gCACE,uCACA,kCACA,2CACA,8CACA,mDACA,uCACA,0CACA,sCACA,8BACA,4BACA,mCACA,0CCxFJ,WACE,kDACA,iCACA,kBACA,WAEF,iBACE,aACA,eACA,8BAfF,YAiBE,mBAjBF,6BAoBA,sBACE,gBAEF,2BACE,iCACA,aACA,OACA,kBACA,iBAEF,oCACE,mBACA,oBACA,oBACA,kBAEF,kBACE,mBACA,yBACA,aAvCF,gBAyCE,oBAEF,kBACE,oBACA,gBACA,WAEF,mBACE,aACA,OACA,eACA,gBApDF,mBAuDE,kBAEF,oBACE,mBACA,aACA,YACA,uBA7DF,8BAiEA,yDAEE,iCAEF,qCACE,6BACA,eAEF,iCACE,aAGF,sHAEE,gBAEF,wDACE,gBAEF,0DACE,gBAEF,2CAvFA,iBA4FA,sBACE,oBACA,cACA,qBACA,iBAEF,yBACE,cACA,eAGF,0CACE,oBACE,aAEF,wCACE,0BAEF,uBA9GF,oBAiHE,oBAjHF,UCMA,yDAEE,wCACA,2CACA,mCACA,oBACA,UAGF,mBACE,+BAGF,SACE,kBACA,aACA,sBACA,SAGF,UACE,aACA,sBACA,UAEF,kBACE,mBACA,mBAEF,iBACE,oBAEF,yBACE,WACA,gBAEF,qBAEE,8BACA,qBACA,mCACA,8BAEF,UAjDA,wBAoDA,WACE,wBACA,qBACA,gBACA,qFACA,yCACA,iCACA,mCA3DF,mDAgEA,eACE,aAEF,yBACE,OAEF,8CAtEA,gBAwEE,sBAEF,4BACE,6BACA,0BAEF,2BACE,4BACA,yBACA,sBAEF,8CAEE,UAGF,gBACE,aACA,kBAEF,0BACE,YAEF,sBACE,kBACA,kDAjGF,oBAmGE,oBACA,4BACA,sDACA,aACA,iBAvGF,mBAyGE,kBACA,aACA,kBACA,aACA,UAEF,0CACE,sBACE,iBC3GJ,sBACE,cACA,aARF,gCAWE,YAEF,oBACE,gBAdF,YAgBE,kBCVF,WACE,+BAMA,aAEF,iBACE,mBACA,aACA,8BAlBF,cAoBE,mBACA,kBACA,4BAEF,6BACE,gBAEF,kCACE,gBAEF,mBACE,mBACA,qBAEF,iDAEE,mBACA,0BACA,mBAEF,0CACE,WACE,eAIJ,WACE,mBACA,mBACA,wCACA,MACA,WACA,WAEF,iBAtDA,cAwDE,mBACA,wBAEF,6BACE,gBAEF,kCACE,kBAEF,eACE,mBACA,aACA,cACA,8BAEF,wBACE,mBACA,aACA,YACA,yBACA,WAEF,6BACE,YAEF,uBACE,mBACA,mBAEF,gBACE,cACA,YACA,qBACA,eAEF,wBACE,aAEF,oBACE,aAEF,gBACE,oBACA,aACA,YACA,gBArGF,mBAyGA,0CACE,oBACE,oBACA,oBACA,UAEF,gBACE,yBAEF,mBACE,cAGJ,yDAEE,mBACA,yCACA,sCACA,oBACA,oBA5HF,qCA+HE,kBACA,qBACA,WAEF,yEAEE,oCACA,iBAEF,4BACE,iCACA,oBAEF,6EAEE,cA9IF,4BAkJA,uGAEE,mBAGF,mBACE,4DACA,YACA,cACA,iBACA,aAEF,2BACE,aAEF,0BACE,gFACA,6HAIF,yBACE,YAEF,oBACE,aAEF,0BACE,cAEF,6CACE,aAEF,4BACE,gBACA,gBACA,iBAEF,qDACE,aAGF,0CACE,wBACE,WAEF,eACE,OAEF,oBACE,aAEF,4BACE,aAEF,wBACE,iBAIJ,qBACE,wBACA,YACA,UACA,gBACA,eACA,QACA,MACA,0BACA,qCACA,UACA,WAEF,0CACE,qBACE,cAGJ,+BACE,uBAEF,4BACE,mBACA,aACA,8BAEF,0BACE,cACA,YA1OF,YA4OE,eAEF,0BACE,gBA/OF,mBAmPA,8BACE,mBApPF,eAuPA,sCACE,6BAxPF,oBA2PA,2BACE,aACA,YACA,OACA,eACA,MACA,WACA,WAEF,0DACE,+BACA,cACA,YCjQF,SACE,YACA,eACA,2BACA,WAEF,mBACE,8GAGF,mBACE,6HAIF,mDACE,6HAGF,qCACE,4GAGF,oCACE,iEACE,6HAGF,mDACE,gHC7BJ,YACE,wBACA,kBACA,mBACA,wBACA,WAEF,oBACE,8CAEF,qBACE,iDACA,oBAEF,mBACE,+CAGF,qBACE,wBAGF,gDACE,YAEF,oCACE,8DACE,aCjCJ,OACE,kBACA,OAAS,QACT,uBACA,0BACA,kBACA,wBACA,2BACA,mBARF,YAUE,aAVF,YAYE,iBACA,WACA,cAGF,mBACE,aAGF,iBACE,eACA,MAAQ,QAAU,SAAW,OAC7B,0BAGF,iBACE,eACA,MAAQ,QAAU,SAAW,OAG/B,aACE,eACA,QACA,2BC3BF,UACE,mCACA,qBACA,mCACA,SACA,6BACA,wBACA,aACA,sBACA,SACA,gBACA,eACA,eACA,MAEF,eACE,iBAEF,iBACE,YAEF,cACE,YAEF,cACE,YAEF,iBACE,aACA,8BAEF,oBACE,kBACA,oBAEF,eACE,YACA,gBACA,gBAEF,kBACE,iBAIF,8CACE,qCACE,UACE,mBClDN,SACE,oBAEA,aACA,sBAGF,YACE,gBACA,eAEF,yBACE,sBAEF,cACE,aAEF,8CACE,cAEF,0CACE,kGAGA,gBA9BF,uBAiCA,WACE,+BACA,cACA,mBACA,gBArCF,kCAuCE,kBACA,uBACA,iBACA,mBAEF,yCAEE,cACA,eACA,gBACA,mBAjDF,eAoDA,kCAEE,0BACA,UAEF,+BACE,wBACA,gBAEF,8FAEE,kDAEF,+CACE,qBAEF,2BACE,qBACA,kBAEF,2BACE,oBAEF,2BACE,2DACA,mBACA,mBAEF,sJAEE,4CAlFF,kBAoFE,WACA,cACA,gBACA,cACA,kBACA,WACA,eAEF,wHAEE,uCACA,6CACA,eACA,oCACA,WACA,cACA,SACA,WACA,kBACA,YACA,gCACA,QAEF,4GAEE,wBAEF,4HAEE,YACA,WAEF,+CACE,qDC/GF,WANA,iBASA,cACE,aACA,SAEF,cACE,uCACA,aACA,eACA,gBAjBF,iBAoBA,4BACE,wCAEF,oBACE,wCAEF,aACE,mBACA,+BACA,oBAEF,sBACE,qBAEF,8BACE,wBC7BF,YACE,mCACA,eACA,qBACA,kBAEF,oBACE,gBAEF,wEAEE,aAEF,wBACE,2BAEF,cACE,uCACA,qBACA,mCACA,wBACA,iBACA,yBACA,iBA7BF,cA+BE,kBACA,WACA,mBACA,YACA,YCLF,MAEE,eAGA,YAGA,wGAKA,6CACA,wBACA,6CACA,gEAGF,kBACE,mDAEF,oCACE,gCACE,oDAGJ,0BACE,MACE,iBACA,YACA,yGAKJ,0BACE,MACE,gBAGJ,2BACE,MACE,kBAIJ,SACE,uCAGF,KACE,yCACA,aACA,sBACA,iBACA,kBAOA,iCAGF,cACE,aACA,sBACA,YACA,YACA,mBAEF,YACE,aACA,iBACA,SA1GF,cA4GE,gBACA,iBACA,2BACA,WAEF,oBACE,uBAlHF",
   "names": []
 }
diff --git a/static/frontend/frontend.ts b/static/frontend/frontend.ts
index b5f3d24..6cf19a2 100644
--- a/static/frontend/frontend.ts
+++ b/static/frontend/frontend.ts
@@ -40,15 +40,7 @@
 
 // Temporary shortcut for testing out the dark theme.
 keyboard.on('t', 'toggle theme', () => {
-  let nextTheme = 'dark';
-  const theme = document.documentElement.getAttribute('data-theme');
-  if (theme === 'dark') {
-    nextTheme = 'light';
-  } else if (theme === 'light') {
-    nextTheme = 'auto';
-  }
-  document.documentElement.setAttribute('data-theme', nextTheme);
-  document.cookie = `prefers-color-scheme=${nextTheme};path=/;max-age=31536000;`;
+  toggleTheme();
 });
 
 // Pressing '/' focuses the search box
@@ -111,3 +103,24 @@
 } else {
   removeUTMSource();
 }
+
+for (const el of document.querySelectorAll('.js-toggleTheme')) {
+  el.addEventListener('click', () => {
+    toggleTheme();
+  });
+}
+
+/**
+ * toggleTheme switches the preferred color scheme between auto, light, and dark.
+ */
+function toggleTheme() {
+  let nextTheme = 'dark';
+  const theme = document.documentElement.getAttribute('data-theme');
+  if (theme === 'dark') {
+    nextTheme = 'light';
+  } else if (theme === 'light') {
+    nextTheme = 'auto';
+  }
+  document.documentElement.setAttribute('data-theme', nextTheme);
+  document.cookie = `prefers-color-scheme=${nextTheme};path=/;max-age=31536000;`;
+}
diff --git a/static/frontend/unit/main/main.js b/static/frontend/unit/main/main.js
index 53990ab..4fb7a88 100644
--- a/static/frontend/unit/main/main.js
+++ b/static/frontend/unit/main/main.js
@@ -1,4 +1,4 @@
-var m={PLAY_HREF:".js-exampleHref",PLAY_CONTAINER:".js-exampleContainer",EXAMPLE_INPUT:".Documentation-exampleCode",EXAMPLE_OUTPUT:".Documentation-exampleOutput",EXAMPLE_ERROR:".Documentation-exampleError",PLAY_BUTTON:".Documentation-examplePlayButton",SHARE_BUTTON:".Documentation-exampleShareButton",FORMAT_BUTTON:".Documentation-exampleFormatButton",RUN_BUTTON:".Documentation-exampleRunButton"},M=class{constructor(e){this.exampleEl=e;var t,i,s,a;this.exampleEl=e,this.anchorEl=e.querySelector("a"),this.errorEl=e.querySelector(m.EXAMPLE_ERROR),this.playButtonEl=e.querySelector(m.PLAY_BUTTON),this.shareButtonEl=e.querySelector(m.SHARE_BUTTON),this.formatButtonEl=e.querySelector(m.FORMAT_BUTTON),this.runButtonEl=e.querySelector(m.RUN_BUTTON),this.inputEl=this.makeTextArea(e.querySelector(m.EXAMPLE_INPUT)),this.outputEl=e.querySelector(m.EXAMPLE_OUTPUT),(t=this.playButtonEl)==null||t.addEventListener("click",()=>this.handleShareButtonClick()),(i=this.shareButtonEl)==null||i.addEventListener("click",()=>this.handleShareButtonClick()),(s=this.formatButtonEl)==null||s.addEventListener("click",()=>this.handleFormatButtonClick()),(a=this.runButtonEl)==null||a.addEventListener("click",()=>this.handleRunButtonClick()),!!this.inputEl&&(this.resize(),this.inputEl.addEventListener("keyup",()=>this.resize()),this.inputEl.addEventListener("keydown",n=>this.onKeydown(n)))}makeTextArea(e){var i,s;let t=document.createElement("textarea");return t.classList.add("Documentation-exampleCode","code"),t.spellcheck=!1,t.value=(i=e==null?void 0:e.textContent)!=null?i:"",(s=e==null?void 0:e.parentElement)==null||s.replaceChild(t,e),t}getAnchorHash(){var e;return(e=this.anchorEl)==null?void 0:e.hash}expand(){this.exampleEl.open=!0}resize(){var e;if((e=this.inputEl)==null?void 0:e.value){let t=(this.inputEl.value.match(/\n/g)||[]).length;this.inputEl.style.height=`${(20+t*20+12+2)/16}rem`}}onKeydown(e){e.key==="Tab"&&(document.execCommand("insertText",!1,"	"),e.preventDefault())}setInputText(e){this.inputEl&&(this.inputEl.value=e)}setOutputText(e){this.outputEl&&(this.outputEl.textContent=e)}setErrorText(e){this.errorEl&&(this.errorEl.textContent=e),this.setOutputText("An error has occurred\u2026")}handleShareButtonClick(){var t;let e="https://play.golang.org/p/";this.setOutputText("Waiting for remote server\u2026"),fetch("/play/share",{method:"POST",body:(t=this.inputEl)==null?void 0:t.value}).then(i=>i.text()).then(i=>{let s=e+i;this.setOutputText(`<a href="${s}">${s}</a>`),window.open(s)}).catch(i=>{this.setErrorText(i)})}handleFormatButtonClick(){var t,i;this.setOutputText("Waiting for remote server\u2026");let e=new FormData;e.append("body",(i=(t=this.inputEl)==null?void 0:t.value)!=null?i:""),fetch("/play/fmt",{method:"POST",body:e}).then(s=>s.json()).then(({Body:s,Error:a})=>{this.setOutputText(a||"Done."),s&&(this.setInputText(s),this.resize())}).catch(s=>{this.setErrorText(s)})}handleRunButtonClick(){var e;this.setOutputText("Waiting for remote server\u2026"),fetch("/play/compile",{method:"POST",body:JSON.stringify({body:(e=this.inputEl)==null?void 0:e.value,version:2})}).then(t=>t.json()).then(async({Events:t,Errors:i})=>{this.setOutputText(i||"");for(let s of t||[])this.setOutputText(s.Message),await new Promise(a=>setTimeout(a,s.Delay/1e6))}).catch(t=>{this.setErrorText(t)})}};function S(){let r=location.hash.match(/^#(example-.*)$/);if(r){let i=document.getElementById(r[1]);i&&(i.open=!0)}let e=[...document.querySelectorAll(m.PLAY_HREF)],t=i=>e.find(s=>s.hash===i.getAnchorHash());for(let i of document.querySelectorAll(m.PLAY_CONTAINER)){let s=new M(i),a=t(s);a?a.addEventListener("click",()=>{s.expand()}):console.warn("example href not found")}}function H(r,e,t,i){var s;(s=window.dataLayer)!=null||(window.dataLayer=[]),typeof r=="string"?window.dataLayer.push({event:r,event_category:e,event_action:t,event_label:i}):window.dataLayer.push(r)}var O=class{constructor(){this.handlers={},document.addEventListener("keydown",e=>this.handleKeyPress(e))}on(e,t,i,s){var a,n;return(n=(a=this.handlers)[e])!=null||(a[e]=new Set),this.handlers[e].add({description:t,callback:i,...s}),this}handleKeyPress(e){var t;for(let i of(t=this.handlers[e.key.toLowerCase()])!=null?t:new Set){if(i.target&&i.target!==e.target)return;let s=e.target;if(!i.target&&((s==null?void 0:s.tagName)==="INPUT"||(s==null?void 0:s.tagName)==="SELECT"||(s==null?void 0:s.tagName)==="TEXTAREA")||(s==null?void 0:s.isContentEditable)||i.withMeta&&!(e.ctrlKey||e.metaKey)||!i.withMeta&&(e.ctrlKey||e.metaKey))return;H("keypress","hotkeys",`${e.key} pressed`,i.description),i.callback(e)}}},B=new O;var l=document.querySelector(".JumpDialog"),p=l==null?void 0:l.querySelector(".JumpDialog-body"),c=l==null?void 0:l.querySelector(".JumpDialog-list"),u=l==null?void 0:l.querySelector(".JumpDialog-input"),N=document.querySelector(".js-documentation"),h;function $(){let r=[];if(!!N){for(let e of N.querySelectorAll("[data-kind]"))r.push(G(e));for(let e of r)e.link.addEventListener("click",function(){l==null||l.close()});return r.sort(function(e,t){return e.lower.localeCompare(t.lower)}),r}}function G(r){var s;let e=document.createElement("a"),t=r.getAttribute("id");e.setAttribute("href","#"+t),e.setAttribute("tabindex","-1"),e.setAttribute("data-gtmc","jump to link");let i=r.getAttribute("data-kind");return{link:e,name:t!=null?t:"",kind:i!=null?i:"",lower:(s=t==null?void 0:t.toLowerCase())!=null?s:""}}var P,f=-1;function g(r){for(P=r,h||(h=$()),x(-1);c==null?void 0:c.firstChild;)c.firstChild.remove();if(r){let e=r.toLowerCase(),t=[],i=[],s=[],a=(n,o,d)=>n.name.substring(0,o)+"<b>"+n.name.substring(o,d)+"</b>"+n.name.substring(d);for(let n of h!=null?h:[]){let o=n.name.toLowerCase();if(o===e)n.link.innerHTML=a(n,0,n.name.length),t.push(n);else if(o.startsWith(e))n.link.innerHTML=a(n,0,r.length),i.push(n);else{let d=o.indexOf(e);d>-1&&(n.link.innerHTML=a(n,d,d+r.length),s.push(n))}}for(let n of t.concat(i).concat(s))c==null||c.appendChild(n.link)}else{if(!h||h.length===0){let e=document.createElement("i");e.innerHTML="There are no symbols on this page.",c==null||c.appendChild(e)}for(let e of h!=null?h:[])e.link.innerHTML=e.name+" <i>"+e.kind+"</i>",c==null||c.appendChild(e.link)}p&&(p.scrollTop=0),(h==null?void 0:h.length)&&c&&c.children.length>0&&x(0)}function x(r){let e=c==null?void 0:c.children;if(!(!e||!p)){if(f>=0&&e[f].classList.remove("JumpDialog-active"),r>=e.length&&(r=e.length-1),r>=0){e[r].classList.add("JumpDialog-active");let t=e[r].offsetTop-e[0].offsetTop,i=t+e[r].clientHeight;t<p.scrollTop?p.scrollTop=t:i>p.scrollTop+p.clientHeight&&(p.scrollTop=i-p.clientHeight)}f=r}}function R(r){if(f<0)return;let e=f+r;e<0&&(e=0),x(e)}function q(){u==null||u.addEventListener("keyup",function(){u.value.toUpperCase()!=P.toUpperCase()&&g(u.value)}),u==null||u.addEventListener("keydown",function(t){let i=38,s=40,a=13;switch(t.which){case i:R(-1),t.preventDefault();break;case s:R(1),t.preventDefault();break;case a:f>=0&&c&&(c.children[f].click(),t.preventDefault());break}});let r=document.querySelector(".ShortcutsDialog");B.on("f","open jump to modal",t=>{(l==null?void 0:l.open)||(r==null?void 0:r.open)||(t.preventDefault(),u&&(u.value=""),l==null||l.showModal(),u==null||u.focus(),g(""))}).on("?","open shortcuts modal",()=>{(l==null?void 0:l.open)||(r==null?void 0:r.open)||r==null||r.showModal()});let e=document.querySelector(".js-jumpToInput");e&&e.addEventListener("click",()=>{u&&(u.value=""),g("")})}var y=class{constructor(e){this.el=e;this.el.addEventListener("change",t=>{let i=t.target,s=i.value;i.value.startsWith("/")||(s="/"+s),window.location.href=s})}};function F(r){let e=document.createElement("label");e.classList.add("go-Label"),e.setAttribute("aria-label","Menu");let t=document.createElement("select");t.classList.add("go-Select","js-selectNav"),e.appendChild(t);let i=document.createElement("optgroup");i.label="Outline",t.appendChild(i);let s={},a;for(let n of r.treeitems){if(Number(n.depth)>4)continue;n.groupTreeitem?(a=s[n.groupTreeitem.label],a||(a=s[n.groupTreeitem.label]=document.createElement("optgroup"),a.label=n.groupTreeitem.label,t.appendChild(a))):a=i;let o=document.createElement("option");o.label=n.label,o.textContent=n.label,o.value=n.el.href.replace(window.location.origin,"").replace("/",""),a.appendChild(o)}return r.addObserver(n=>{var b;let o=n.el.hash,d=(b=t.querySelector(`[value$="${o}"]`))==null?void 0:b.value;d&&(t.value=d)},50),e}var L=class{constructor(e){this.el=e;this.handleResize=()=>{this.el.style.setProperty("--js-tree-height","100vh"),this.el.style.setProperty("--js-tree-height",this.el.clientHeight+"px")};this.treeitems=[],this.firstChars=[],this.firstTreeitem=null,this.lastTreeitem=null,this.observerCallbacks=[],this.init()}init(){this.handleResize(),window.addEventListener("resize",this.handleResize),this.findTreeItems(),this.updateVisibleTreeitems(),this.observeTargets(),this.firstTreeitem&&(this.firstTreeitem.el.tabIndex=0)}observeTargets(){this.addObserver(i=>{this.expandTreeitem(i),this.setSelected(i)});let e=new Map,t=new IntersectionObserver(i=>{for(let s of i)e.set(s.target.id,s.isIntersecting||s.intersectionRatio===1);for(let[s,a]of e)if(a){let n=this.treeitems.find(o=>{var d;return(d=o.el)==null?void 0:d.href.endsWith(`#${s}`)});if(n)for(let o of this.observerCallbacks)o(n);break}},{threshold:1,rootMargin:"-60px 0px 0px 0px"});for(let i of this.treeitems.map(s=>s.el.getAttribute("href")))if(i){let s=i.replace(window.location.origin,"").replace("/","").replace("#",""),a=document.getElementById(s);a&&t.observe(a)}}addObserver(e,t=200){this.observerCallbacks.push(W(e,t))}setFocusToNextItem(e){let t=null;for(let i=e.index+1;i<this.treeitems.length;i++){let s=this.treeitems[i];if(s.isVisible){t=s;break}}t&&this.setFocusToItem(t)}setFocusToPreviousItem(e){let t=null;for(let i=e.index-1;i>-1;i--){let s=this.treeitems[i];if(s.isVisible){t=s;break}}t&&this.setFocusToItem(t)}setFocusToParentItem(e){e.groupTreeitem&&this.setFocusToItem(e.groupTreeitem)}setFocusToFirstItem(){this.firstTreeitem&&this.setFocusToItem(this.firstTreeitem)}setFocusToLastItem(){this.lastTreeitem&&this.setFocusToItem(this.lastTreeitem)}setSelected(e){var t;for(let i of this.el.querySelectorAll('[aria-expanded="true"]'))i!==e.el&&(((t=i.nextElementSibling)==null?void 0:t.contains(e.el))||i.setAttribute("aria-expanded","false"));for(let i of this.el.querySelectorAll("[aria-selected]"))i!==e.el&&i.setAttribute("aria-selected","false");e.el.setAttribute("aria-selected","true"),this.updateVisibleTreeitems(),this.setFocusToItem(e,!1)}expandTreeitem(e){let t=e;for(;t;)t.isExpandable&&t.el.setAttribute("aria-expanded","true"),t=t.groupTreeitem;this.updateVisibleTreeitems()}expandAllSiblingItems(e){for(let t of this.treeitems)t.groupTreeitem===e.groupTreeitem&&t.isExpandable&&this.expandTreeitem(t)}collapseTreeitem(e){let t=null;e.isExpanded()?t=e:t=e.groupTreeitem,t&&(t.el.setAttribute("aria-expanded","false"),this.updateVisibleTreeitems(),this.setFocusToItem(t))}setFocusByFirstCharacter(e,t){let i,s;t=t.toLowerCase(),i=e.index+1,i===this.treeitems.length&&(i=0),s=this.getIndexFirstChars(i,t),s===-1&&(s=this.getIndexFirstChars(0,t)),s>-1&&this.setFocusToItem(this.treeitems[s])}findTreeItems(){let e=(t,i)=>{let s=i,a=t.firstElementChild;for(;a;)(a.tagName==="A"||a.tagName==="SPAN")&&(s=new _(a,this,i),this.treeitems.push(s),this.firstChars.push(s.label.substring(0,1).toLowerCase())),a.firstElementChild&&e(a,s),a=a.nextElementSibling};e(this.el,null),this.treeitems.map((t,i)=>t.index=i)}updateVisibleTreeitems(){this.firstTreeitem=this.treeitems[0];for(let e of this.treeitems){let t=e.groupTreeitem;for(e.isVisible=!0;t&&t.el!==this.el;)t.isExpanded()||(e.isVisible=!1),t=t.groupTreeitem;e.isVisible&&(this.lastTreeitem=e)}}setFocusToItem(e,t=!0){e.el.tabIndex=0,t&&e.el.focus();for(let i of this.treeitems)i!==e&&(i.el.tabIndex=-1)}getIndexFirstChars(e,t){for(let i=e;i<this.firstChars.length;i++)if(this.treeitems[i].isVisible&&t===this.firstChars[i])return i;return-1}},_=class{constructor(e,t,i){var n,o,d,b,C;e.tabIndex=-1,this.el=e,this.groupTreeitem=i,this.label=(o=(n=e.textContent)==null?void 0:n.trim())!=null?o:"",this.tree=t,this.depth=((i==null?void 0:i.depth)||0)+1,this.index=0;let s=e.parentElement;(s==null?void 0:s.tagName.toLowerCase())==="li"&&(s==null||s.setAttribute("role","none")),e.setAttribute("aria-level",this.depth+""),e.getAttribute("aria-label")&&(this.label=(b=(d=e==null?void 0:e.getAttribute("aria-label"))==null?void 0:d.trim())!=null?b:""),this.isExpandable=!1,this.isVisible=!1,this.isInGroup=!!i;let a=e.nextElementSibling;for(;a;){if(a.tagName.toLowerCase()=="ul"){let I=`${(C=i==null?void 0:i.label)!=null?C:""} nav group ${this.label}`.replace(/[\W_]+/g,"_");e.setAttribute("aria-owns",I),e.setAttribute("aria-expanded","false"),a.setAttribute("role","group"),a.setAttribute("id",I),this.isExpandable=!0;break}a=a.nextElementSibling}this.init()}init(){this.el.tabIndex=-1,this.el.getAttribute("role")||this.el.setAttribute("role","treeitem"),this.el.addEventListener("keydown",this.handleKeydown.bind(this)),this.el.addEventListener("click",this.handleClick.bind(this)),this.el.addEventListener("focus",this.handleFocus.bind(this)),this.el.addEventListener("blur",this.handleBlur.bind(this))}isExpanded(){return this.isExpandable?this.el.getAttribute("aria-expanded")==="true":!1}isSelected(){return this.el.getAttribute("aria-selected")==="true"}handleClick(e){e.target!==this.el&&e.target!==this.el.firstElementChild||(this.isExpandable&&(this.isExpanded()&&this.isSelected()?this.tree.collapseTreeitem(this):this.tree.expandTreeitem(this),e.stopPropagation()),this.tree.setSelected(this))}handleFocus(){var t;let e=this.el;this.isExpandable&&(e=(t=e.firstElementChild)!=null?t:e),e.classList.add("focus")}handleBlur(){var t;let e=this.el;this.isExpandable&&(e=(t=e.firstElementChild)!=null?t:e),e.classList.remove("focus")}handleKeydown(e){if(e.altKey||e.ctrlKey||e.metaKey)return;let t=!1;switch(e.key){case" ":case"Enter":this.isExpandable?(this.isExpanded()&&this.isSelected()?this.tree.collapseTreeitem(this):this.tree.expandTreeitem(this),t=!0):e.stopPropagation(),this.tree.setSelected(this);break;case"ArrowUp":this.tree.setFocusToPreviousItem(this),t=!0;break;case"ArrowDown":this.tree.setFocusToNextItem(this),t=!0;break;case"ArrowRight":this.isExpandable&&(this.isExpanded()?this.tree.setFocusToNextItem(this):this.tree.expandTreeitem(this)),t=!0;break;case"ArrowLeft":this.isExpandable&&this.isExpanded()?(this.tree.collapseTreeitem(this),t=!0):this.isInGroup&&(this.tree.setFocusToParentItem(this),t=!0);break;case"Home":this.tree.setFocusToFirstItem(),t=!0;break;case"End":this.tree.setFocusToLastItem(),t=!0;break;default:e.key.length===1&&e.key.match(/\S/)&&(e.key=="*"?this.tree.expandAllSiblingItems(this):this.tree.setFocusByFirstCharacter(this,e.key),t=!0);break}t&&(e.stopPropagation(),e.preventDefault())}};function W(r,e){let t;return(...i)=>{let s=()=>{t=null,r(...i)};t&&clearTimeout(t),t=setTimeout(s,e)}}var A=class{constructor(e,t){this.table=e;this.toggleAll=t;this.expandAllItems=()=>{this.toggles.map(e=>e.setAttribute("aria-expanded","true")),this.update()};this.collapseAllItems=()=>{this.toggles.map(e=>e.setAttribute("aria-expanded","false")),this.update()};this.update=()=>{this.updateVisibleItems(),setTimeout(()=>this.updateGlobalToggle())};this.rows=Array.from(e.querySelectorAll("[data-aria-controls]")),this.toggles=Array.from(this.table.querySelectorAll("[aria-expanded]")),this.setAttributes(),this.attachEventListeners(),this.update()}setAttributes(){for(let e of["data-aria-controls","data-aria-labelledby","data-id"])this.table.querySelectorAll(`[${e}]`).forEach(t=>{var i;t.setAttribute(e.replace("data-",""),(i=t.getAttribute(e))!=null?i:""),t.removeAttribute(e)})}attachEventListeners(){var e;this.rows.forEach(t=>{t.addEventListener("click",i=>{this.handleToggleClick(i)})}),(e=this.toggleAll)==null||e.addEventListener("click",()=>{this.expandAllItems()}),document.addEventListener("keydown",t=>{(t.ctrlKey||t.metaKey)&&t.key==="f"&&this.expandAllItems()})}handleToggleClick(e){let t=e.currentTarget;(t==null?void 0:t.hasAttribute("aria-expanded"))||(t=this.table.querySelector(`button[aria-controls="${t==null?void 0:t.getAttribute("aria-controls")}"]`));let i=(t==null?void 0:t.getAttribute("aria-expanded"))==="true";t==null||t.setAttribute("aria-expanded",i?"false":"true"),e.stopPropagation(),this.update()}updateVisibleItems(){this.rows.map(e=>{var s;let t=(e==null?void 0:e.getAttribute("aria-expanded"))==="true",i=(s=e==null?void 0:e.getAttribute("aria-controls"))==null?void 0:s.trimEnd().split(" ");i==null||i.map(a=>{let n=document.getElementById(`${a}`);t?(n==null||n.classList.add("visible"),n==null||n.classList.remove("hidden")):(n==null||n.classList.add("hidden"),n==null||n.classList.remove("visible"))})})}updateGlobalToggle(){if(!this.toggleAll)return;this.rows.some(t=>t.hasAttribute("aria-expanded"))&&(this.toggleAll.style.display="block"),this.toggles.some(t=>t.getAttribute("aria-expanded")==="false")?(this.toggleAll.innerText="Expand all",this.toggleAll.onclick=this.expandAllItems):(this.toggleAll.innerText="Collapse all",this.toggleAll.onclick=this.collapseAllItems)}};q();S();var K=document.querySelector(".js-expandableTable");if(K){let r=new A(K,document.querySelector(".js-expandAllDirectories"));window.location.search.includes("expand-directories")&&r.expandAllItems()}var U=document.querySelector(".js-tree");if(U){let r=new L(U),e=F(r),t=document.querySelector(".js-mainNavMobile");t&&t.firstElementChild&&(t==null||t.replaceChild(e,t.firstElementChild)),e.firstElementChild&&new y(e.firstElementChild)}var E=document.querySelector(".js-readme"),w=document.querySelector(".js-readmeContent"),D=document.querySelector(".js-readmeOutline"),v=document.querySelectorAll(".js-readmeExpand"),V=document.querySelector(".js-readmeCollapse"),k=document.querySelector(".DocNavMobile-select");E&&w&&D&&v.length&&V&&(window.location.hash.includes("readme")&&T(),k==null||k.addEventListener("change",r=>{r.target.value.startsWith("readme-")&&T()}),v.forEach(r=>r.addEventListener("click",e=>{e.preventDefault(),T(),E.scrollIntoView()})),V.addEventListener("click",r=>{r.preventDefault(),E.classList.remove("UnitReadme--expanded"),v[1]&&v[1].scrollIntoView({block:"center"})}),w.addEventListener("keyup",()=>{T()}),w.addEventListener("click",()=>{T()}),D.addEventListener("click",()=>{T()}),document.addEventListener("keydown",r=>{(r.ctrlKey||r.metaKey)&&r.key==="f"&&T()}));function T(){history.replaceState(null,"",`${location.pathname}#section-readme`),E==null||E.classList.add("UnitReadme--expanded")}function J(){var t;if(!location.hash)return;let r=document.getElementById(location.hash.slice(1)),e=(t=r==null?void 0:r.parentElement)==null?void 0:t.parentElement;(e==null?void 0:e.nodeName)==="DETAILS"&&(e.open=!0)}J();window.addEventListener("hashchange",()=>J());document.querySelectorAll(".js-buildContextSelect").forEach(r=>{r.addEventListener("change",e=>{window.location.search=`?GOOS=${e.target.value}`})});
+var m={PLAY_HREF:".js-exampleHref",PLAY_CONTAINER:".js-exampleContainer",EXAMPLE_INPUT:".Documentation-exampleCode",EXAMPLE_OUTPUT:".Documentation-exampleOutput",EXAMPLE_ERROR:".Documentation-exampleError",PLAY_BUTTON:".Documentation-examplePlayButton",SHARE_BUTTON:".Documentation-exampleShareButton",FORMAT_BUTTON:".Documentation-exampleFormatButton",RUN_BUTTON:".Documentation-exampleRunButton"},I=class{constructor(e){this.exampleEl=e;var t,i,s,l;this.exampleEl=e,this.anchorEl=e.querySelector("a"),this.errorEl=e.querySelector(m.EXAMPLE_ERROR),this.playButtonEl=e.querySelector(m.PLAY_BUTTON),this.shareButtonEl=e.querySelector(m.SHARE_BUTTON),this.formatButtonEl=e.querySelector(m.FORMAT_BUTTON),this.runButtonEl=e.querySelector(m.RUN_BUTTON),this.inputEl=this.makeTextArea(e.querySelector(m.EXAMPLE_INPUT)),this.outputEl=e.querySelector(m.EXAMPLE_OUTPUT),(t=this.playButtonEl)==null||t.addEventListener("click",()=>this.handleShareButtonClick()),(i=this.shareButtonEl)==null||i.addEventListener("click",()=>this.handleShareButtonClick()),(s=this.formatButtonEl)==null||s.addEventListener("click",()=>this.handleFormatButtonClick()),(l=this.runButtonEl)==null||l.addEventListener("click",()=>this.handleRunButtonClick()),!!this.inputEl&&(this.resize(),this.inputEl.addEventListener("keyup",()=>this.resize()),this.inputEl.addEventListener("keydown",r=>this.onKeydown(r)))}makeTextArea(e){var i,s;let t=document.createElement("textarea");return t.classList.add("Documentation-exampleCode","code"),t.spellcheck=!1,t.value=(i=e==null?void 0:e.textContent)!=null?i:"",(s=e==null?void 0:e.parentElement)==null||s.replaceChild(t,e),t}getAnchorHash(){var e;return(e=this.anchorEl)==null?void 0:e.hash}expand(){this.exampleEl.open=!0}resize(){var e;if((e=this.inputEl)==null?void 0:e.value){let t=(this.inputEl.value.match(/\n/g)||[]).length;this.inputEl.style.height=`${(20+t*20+12+2)/16}rem`}}onKeydown(e){e.key==="Tab"&&(document.execCommand("insertText",!1,"	"),e.preventDefault())}setInputText(e){this.inputEl&&(this.inputEl.value=e)}setOutputText(e){this.outputEl&&(this.outputEl.textContent=e)}setErrorText(e){this.errorEl&&(this.errorEl.textContent=e),this.setOutputText("An error has occurred\u2026")}handleShareButtonClick(){var t;let e="https://play.golang.org/p/";this.setOutputText("Waiting for remote server\u2026"),fetch("/play/share",{method:"POST",body:(t=this.inputEl)==null?void 0:t.value}).then(i=>i.text()).then(i=>{let s=e+i;this.setOutputText(`<a href="${s}">${s}</a>`),window.open(s)}).catch(i=>{this.setErrorText(i)})}handleFormatButtonClick(){var t,i;this.setOutputText("Waiting for remote server\u2026");let e=new FormData;e.append("body",(i=(t=this.inputEl)==null?void 0:t.value)!=null?i:""),fetch("/play/fmt",{method:"POST",body:e}).then(s=>s.json()).then(({Body:s,Error:l})=>{this.setOutputText(l||"Done."),s&&(this.setInputText(s),this.resize())}).catch(s=>{this.setErrorText(s)})}handleRunButtonClick(){var e;this.setOutputText("Waiting for remote server\u2026"),fetch("/play/compile",{method:"POST",body:JSON.stringify({body:(e=this.inputEl)==null?void 0:e.value,version:2})}).then(t=>t.json()).then(async({Events:t,Errors:i})=>{this.setOutputText(i||"");for(let s of t||[])this.setOutputText(s.Message),await new Promise(l=>setTimeout(l,s.Delay/1e6))}).catch(t=>{this.setErrorText(t)})}};function S(){let n=location.hash.match(/^#(example-.*)$/);if(n){let i=document.getElementById(n[1]);i&&(i.open=!0)}let e=[...document.querySelectorAll(m.PLAY_HREF)],t=i=>e.find(s=>s.hash===i.getAnchorHash());for(let i of document.querySelectorAll(m.PLAY_CONTAINER)){let s=new I(i),l=t(s);l?l.addEventListener("click",()=>{s.expand()}):console.warn("example href not found")}}function H(n,e,t,i){var s;(s=window.dataLayer)!=null||(window.dataLayer=[]),typeof n=="string"?window.dataLayer.push({event:n,event_category:e,event_action:t,event_label:i}):window.dataLayer.push(n)}var O=class{constructor(){this.handlers={},document.addEventListener("keydown",e=>this.handleKeyPress(e))}on(e,t,i,s){var l,r;return(r=(l=this.handlers)[e])!=null||(l[e]=new Set),this.handlers[e].add({description:t,callback:i,...s}),this}handleKeyPress(e){var t;for(let i of(t=this.handlers[e.key.toLowerCase()])!=null?t:new Set){if(i.target&&i.target!==e.target)return;let s=e.target;if(!i.target&&((s==null?void 0:s.tagName)==="INPUT"||(s==null?void 0:s.tagName)==="SELECT"||(s==null?void 0:s.tagName)==="TEXTAREA")||(s==null?void 0:s.isContentEditable)||i.withMeta&&!(e.ctrlKey||e.metaKey)||!i.withMeta&&(e.ctrlKey||e.metaKey))return;H("keypress","hotkeys",`${e.key} pressed`,i.description),i.callback(e)}}},B=new O;var a=document.querySelector(".JumpDialog"),p=a==null?void 0:a.querySelector(".JumpDialog-body"),c=a==null?void 0:a.querySelector(".JumpDialog-list"),u=a==null?void 0:a.querySelector(".JumpDialog-input"),N=document.querySelector(".js-documentation"),h;function $(){let n=[];if(!!N){for(let e of N.querySelectorAll("[data-kind]"))n.push(G(e));for(let e of n)e.link.addEventListener("click",function(){a==null||a.close()});return n.sort(function(e,t){return e.lower.localeCompare(t.lower)}),n}}function G(n){var s;let e=document.createElement("a"),t=n.getAttribute("id");e.setAttribute("href","#"+t),e.setAttribute("tabindex","-1"),e.setAttribute("data-gtmc","jump to link");let i=n.getAttribute("data-kind");return{link:e,name:t!=null?t:"",kind:i!=null?i:"",lower:(s=t==null?void 0:t.toLowerCase())!=null?s:""}}var P,f=-1;function g(n){for(P=n,h||(h=$()),x(-1);c==null?void 0:c.firstChild;)c.firstChild.remove();if(n){let e=n.toLowerCase(),t=[],i=[],s=[],l=(r,o,d)=>r.name.substring(0,o)+"<b>"+r.name.substring(o,d)+"</b>"+r.name.substring(d);for(let r of h!=null?h:[]){let o=r.name.toLowerCase();if(o===e)r.link.innerHTML=l(r,0,r.name.length),t.push(r);else if(o.startsWith(e))r.link.innerHTML=l(r,0,n.length),i.push(r);else{let d=o.indexOf(e);d>-1&&(r.link.innerHTML=l(r,d,d+n.length),s.push(r))}}for(let r of t.concat(i).concat(s))c==null||c.appendChild(r.link)}else{if(!h||h.length===0){let e=document.createElement("i");e.innerHTML="There are no symbols on this page.",c==null||c.appendChild(e)}for(let e of h!=null?h:[])e.link.innerHTML=e.name+" <i>"+e.kind+"</i>",c==null||c.appendChild(e.link)}p&&(p.scrollTop=0),(h==null?void 0:h.length)&&c&&c.children.length>0&&x(0)}function x(n){let e=c==null?void 0:c.children;if(!(!e||!p)){if(f>=0&&e[f].classList.remove("JumpDialog-active"),n>=e.length&&(n=e.length-1),n>=0){e[n].classList.add("JumpDialog-active");let t=e[n].offsetTop-e[0].offsetTop,i=t+e[n].clientHeight;t<p.scrollTop?p.scrollTop=t:i>p.scrollTop+p.clientHeight&&(p.scrollTop=i-p.clientHeight)}f=n}}function R(n){if(f<0)return;let e=f+n;e<0&&(e=0),x(e)}function q(){var t;u==null||u.addEventListener("keyup",function(){u.value.toUpperCase()!=P.toUpperCase()&&g(u.value)}),u==null||u.addEventListener("keydown",function(i){let s=38,l=40,r=13;switch(i.which){case s:R(-1),i.preventDefault();break;case l:R(1),i.preventDefault();break;case r:f>=0&&c&&(c.children[f].click(),i.preventDefault());break}});let n=document.querySelector(".ShortcutsDialog");B.on("f","open jump to modal",i=>{(a==null?void 0:a.open)||(n==null?void 0:n.open)||(i.preventDefault(),u&&(u.value=""),a==null||a.showModal(),u==null||u.focus(),g(""))}).on("?","open shortcuts modal",()=>{(a==null?void 0:a.open)||(n==null?void 0:n.open)||n==null||n.showModal()});let e=document.querySelector(".js-jumpToInput");e&&e.addEventListener("click",()=>{u&&(u.value=""),g("")}),(t=document.querySelector(".js-openShortcuts"))==null||t.addEventListener("click",()=>{n==null||n.showModal()})}var y=class{constructor(e){this.el=e;this.el.addEventListener("change",t=>{let i=t.target,s=i.value;i.value.startsWith("/")||(s="/"+s),window.location.href=s})}};function F(n){let e=document.createElement("label");e.classList.add("go-Label"),e.setAttribute("aria-label","Menu");let t=document.createElement("select");t.classList.add("go-Select","js-selectNav"),e.appendChild(t);let i=document.createElement("optgroup");i.label="Outline",t.appendChild(i);let s={},l;for(let r of n.treeitems){if(Number(r.depth)>4)continue;r.groupTreeitem?(l=s[r.groupTreeitem.label],l||(l=s[r.groupTreeitem.label]=document.createElement("optgroup"),l.label=r.groupTreeitem.label,t.appendChild(l))):l=i;let o=document.createElement("option");o.label=r.label,o.textContent=r.label,o.value=r.el.href.replace(window.location.origin,"").replace("/",""),l.appendChild(o)}return n.addObserver(r=>{var b;let o=r.el.hash,d=(b=t.querySelector(`[value$="${o}"]`))==null?void 0:b.value;d&&(t.value=d)},50),e}var L=class{constructor(e){this.el=e;this.handleResize=()=>{this.el.style.setProperty("--js-tree-height","100vh"),this.el.style.setProperty("--js-tree-height",this.el.clientHeight+"px")};this.treeitems=[],this.firstChars=[],this.firstTreeitem=null,this.lastTreeitem=null,this.observerCallbacks=[],this.init()}init(){this.handleResize(),window.addEventListener("resize",this.handleResize),this.findTreeItems(),this.updateVisibleTreeitems(),this.observeTargets(),this.firstTreeitem&&(this.firstTreeitem.el.tabIndex=0)}observeTargets(){this.addObserver(i=>{this.expandTreeitem(i),this.setSelected(i)});let e=new Map,t=new IntersectionObserver(i=>{for(let s of i)e.set(s.target.id,s.isIntersecting||s.intersectionRatio===1);for(let[s,l]of e)if(l){let r=this.treeitems.find(o=>{var d;return(d=o.el)==null?void 0:d.href.endsWith(`#${s}`)});if(r)for(let o of this.observerCallbacks)o(r);break}},{threshold:1,rootMargin:"-60px 0px 0px 0px"});for(let i of this.treeitems.map(s=>s.el.getAttribute("href")))if(i){let s=i.replace(window.location.origin,"").replace("/","").replace("#",""),l=document.getElementById(s);l&&t.observe(l)}}addObserver(e,t=200){this.observerCallbacks.push(W(e,t))}setFocusToNextItem(e){let t=null;for(let i=e.index+1;i<this.treeitems.length;i++){let s=this.treeitems[i];if(s.isVisible){t=s;break}}t&&this.setFocusToItem(t)}setFocusToPreviousItem(e){let t=null;for(let i=e.index-1;i>-1;i--){let s=this.treeitems[i];if(s.isVisible){t=s;break}}t&&this.setFocusToItem(t)}setFocusToParentItem(e){e.groupTreeitem&&this.setFocusToItem(e.groupTreeitem)}setFocusToFirstItem(){this.firstTreeitem&&this.setFocusToItem(this.firstTreeitem)}setFocusToLastItem(){this.lastTreeitem&&this.setFocusToItem(this.lastTreeitem)}setSelected(e){var t;for(let i of this.el.querySelectorAll('[aria-expanded="true"]'))i!==e.el&&(((t=i.nextElementSibling)==null?void 0:t.contains(e.el))||i.setAttribute("aria-expanded","false"));for(let i of this.el.querySelectorAll("[aria-selected]"))i!==e.el&&i.setAttribute("aria-selected","false");e.el.setAttribute("aria-selected","true"),this.updateVisibleTreeitems(),this.setFocusToItem(e,!1)}expandTreeitem(e){let t=e;for(;t;)t.isExpandable&&t.el.setAttribute("aria-expanded","true"),t=t.groupTreeitem;this.updateVisibleTreeitems()}expandAllSiblingItems(e){for(let t of this.treeitems)t.groupTreeitem===e.groupTreeitem&&t.isExpandable&&this.expandTreeitem(t)}collapseTreeitem(e){let t=null;e.isExpanded()?t=e:t=e.groupTreeitem,t&&(t.el.setAttribute("aria-expanded","false"),this.updateVisibleTreeitems(),this.setFocusToItem(t))}setFocusByFirstCharacter(e,t){let i,s;t=t.toLowerCase(),i=e.index+1,i===this.treeitems.length&&(i=0),s=this.getIndexFirstChars(i,t),s===-1&&(s=this.getIndexFirstChars(0,t)),s>-1&&this.setFocusToItem(this.treeitems[s])}findTreeItems(){let e=(t,i)=>{let s=i,l=t.firstElementChild;for(;l;)(l.tagName==="A"||l.tagName==="SPAN")&&(s=new _(l,this,i),this.treeitems.push(s),this.firstChars.push(s.label.substring(0,1).toLowerCase())),l.firstElementChild&&e(l,s),l=l.nextElementSibling};e(this.el,null),this.treeitems.map((t,i)=>t.index=i)}updateVisibleTreeitems(){this.firstTreeitem=this.treeitems[0];for(let e of this.treeitems){let t=e.groupTreeitem;for(e.isVisible=!0;t&&t.el!==this.el;)t.isExpanded()||(e.isVisible=!1),t=t.groupTreeitem;e.isVisible&&(this.lastTreeitem=e)}}setFocusToItem(e,t=!0){e.el.tabIndex=0,t&&e.el.focus();for(let i of this.treeitems)i!==e&&(i.el.tabIndex=-1)}getIndexFirstChars(e,t){for(let i=e;i<this.firstChars.length;i++)if(this.treeitems[i].isVisible&&t===this.firstChars[i])return i;return-1}},_=class{constructor(e,t,i){var r,o,d,b,C;e.tabIndex=-1,this.el=e,this.groupTreeitem=i,this.label=(o=(r=e.textContent)==null?void 0:r.trim())!=null?o:"",this.tree=t,this.depth=((i==null?void 0:i.depth)||0)+1,this.index=0;let s=e.parentElement;(s==null?void 0:s.tagName.toLowerCase())==="li"&&(s==null||s.setAttribute("role","none")),e.setAttribute("aria-level",this.depth+""),e.getAttribute("aria-label")&&(this.label=(b=(d=e==null?void 0:e.getAttribute("aria-label"))==null?void 0:d.trim())!=null?b:""),this.isExpandable=!1,this.isVisible=!1,this.isInGroup=!!i;let l=e.nextElementSibling;for(;l;){if(l.tagName.toLowerCase()=="ul"){let M=`${(C=i==null?void 0:i.label)!=null?C:""} nav group ${this.label}`.replace(/[\W_]+/g,"_");e.setAttribute("aria-owns",M),e.setAttribute("aria-expanded","false"),l.setAttribute("role","group"),l.setAttribute("id",M),this.isExpandable=!0;break}l=l.nextElementSibling}this.init()}init(){this.el.tabIndex=-1,this.el.getAttribute("role")||this.el.setAttribute("role","treeitem"),this.el.addEventListener("keydown",this.handleKeydown.bind(this)),this.el.addEventListener("click",this.handleClick.bind(this)),this.el.addEventListener("focus",this.handleFocus.bind(this)),this.el.addEventListener("blur",this.handleBlur.bind(this))}isExpanded(){return this.isExpandable?this.el.getAttribute("aria-expanded")==="true":!1}isSelected(){return this.el.getAttribute("aria-selected")==="true"}handleClick(e){e.target!==this.el&&e.target!==this.el.firstElementChild||(this.isExpandable&&(this.isExpanded()&&this.isSelected()?this.tree.collapseTreeitem(this):this.tree.expandTreeitem(this),e.stopPropagation()),this.tree.setSelected(this))}handleFocus(){var t;let e=this.el;this.isExpandable&&(e=(t=e.firstElementChild)!=null?t:e),e.classList.add("focus")}handleBlur(){var t;let e=this.el;this.isExpandable&&(e=(t=e.firstElementChild)!=null?t:e),e.classList.remove("focus")}handleKeydown(e){if(e.altKey||e.ctrlKey||e.metaKey)return;let t=!1;switch(e.key){case" ":case"Enter":this.isExpandable?(this.isExpanded()&&this.isSelected()?this.tree.collapseTreeitem(this):this.tree.expandTreeitem(this),t=!0):e.stopPropagation(),this.tree.setSelected(this);break;case"ArrowUp":this.tree.setFocusToPreviousItem(this),t=!0;break;case"ArrowDown":this.tree.setFocusToNextItem(this),t=!0;break;case"ArrowRight":this.isExpandable&&(this.isExpanded()?this.tree.setFocusToNextItem(this):this.tree.expandTreeitem(this)),t=!0;break;case"ArrowLeft":this.isExpandable&&this.isExpanded()?(this.tree.collapseTreeitem(this),t=!0):this.isInGroup&&(this.tree.setFocusToParentItem(this),t=!0);break;case"Home":this.tree.setFocusToFirstItem(),t=!0;break;case"End":this.tree.setFocusToLastItem(),t=!0;break;default:e.key.length===1&&e.key.match(/\S/)&&(e.key=="*"?this.tree.expandAllSiblingItems(this):this.tree.setFocusByFirstCharacter(this,e.key),t=!0);break}t&&(e.stopPropagation(),e.preventDefault())}};function W(n,e){let t;return(...i)=>{let s=()=>{t=null,n(...i)};t&&clearTimeout(t),t=setTimeout(s,e)}}var A=class{constructor(e,t){this.table=e;this.toggleAll=t;this.expandAllItems=()=>{this.toggles.map(e=>e.setAttribute("aria-expanded","true")),this.update()};this.collapseAllItems=()=>{this.toggles.map(e=>e.setAttribute("aria-expanded","false")),this.update()};this.update=()=>{this.updateVisibleItems(),setTimeout(()=>this.updateGlobalToggle())};this.rows=Array.from(e.querySelectorAll("[data-aria-controls]")),this.toggles=Array.from(this.table.querySelectorAll("[aria-expanded]")),this.setAttributes(),this.attachEventListeners(),this.update()}setAttributes(){for(let e of["data-aria-controls","data-aria-labelledby","data-id"])this.table.querySelectorAll(`[${e}]`).forEach(t=>{var i;t.setAttribute(e.replace("data-",""),(i=t.getAttribute(e))!=null?i:""),t.removeAttribute(e)})}attachEventListeners(){var e;this.rows.forEach(t=>{t.addEventListener("click",i=>{this.handleToggleClick(i)})}),(e=this.toggleAll)==null||e.addEventListener("click",()=>{this.expandAllItems()}),document.addEventListener("keydown",t=>{(t.ctrlKey||t.metaKey)&&t.key==="f"&&this.expandAllItems()})}handleToggleClick(e){let t=e.currentTarget;(t==null?void 0:t.hasAttribute("aria-expanded"))||(t=this.table.querySelector(`button[aria-controls="${t==null?void 0:t.getAttribute("aria-controls")}"]`));let i=(t==null?void 0:t.getAttribute("aria-expanded"))==="true";t==null||t.setAttribute("aria-expanded",i?"false":"true"),e.stopPropagation(),this.update()}updateVisibleItems(){this.rows.map(e=>{var s;let t=(e==null?void 0:e.getAttribute("aria-expanded"))==="true",i=(s=e==null?void 0:e.getAttribute("aria-controls"))==null?void 0:s.trimEnd().split(" ");i==null||i.map(l=>{let r=document.getElementById(`${l}`);t?(r==null||r.classList.add("visible"),r==null||r.classList.remove("hidden")):(r==null||r.classList.add("hidden"),r==null||r.classList.remove("visible"))})})}updateGlobalToggle(){if(!this.toggleAll)return;this.rows.some(t=>t.hasAttribute("aria-expanded"))&&(this.toggleAll.style.display="block"),this.toggles.some(t=>t.getAttribute("aria-expanded")==="false")?(this.toggleAll.innerText="Expand all",this.toggleAll.onclick=this.expandAllItems):(this.toggleAll.innerText="Collapse all",this.toggleAll.onclick=this.collapseAllItems)}};q();S();var K=document.querySelector(".js-expandableTable");if(K){let n=new A(K,document.querySelector(".js-expandAllDirectories"));window.location.search.includes("expand-directories")&&n.expandAllItems()}var U=document.querySelector(".js-tree");if(U){let n=new L(U),e=F(n),t=document.querySelector(".js-mainNavMobile");t&&t.firstElementChild&&(t==null||t.replaceChild(e,t.firstElementChild)),e.firstElementChild&&new y(e.firstElementChild)}var E=document.querySelector(".js-readme"),w=document.querySelector(".js-readmeContent"),D=document.querySelector(".js-readmeOutline"),v=document.querySelectorAll(".js-readmeExpand"),V=document.querySelector(".js-readmeCollapse"),k=document.querySelector(".DocNavMobile-select");E&&w&&D&&v.length&&V&&(window.location.hash.includes("readme")&&T(),k==null||k.addEventListener("change",n=>{n.target.value.startsWith("readme-")&&T()}),v.forEach(n=>n.addEventListener("click",e=>{e.preventDefault(),T(),E.scrollIntoView()})),V.addEventListener("click",n=>{n.preventDefault(),E.classList.remove("UnitReadme--expanded"),v[1]&&v[1].scrollIntoView({block:"center"})}),w.addEventListener("keyup",()=>{T()}),w.addEventListener("click",()=>{T()}),D.addEventListener("click",()=>{T()}),document.addEventListener("keydown",n=>{(n.ctrlKey||n.metaKey)&&n.key==="f"&&T()}));function T(){history.replaceState(null,"",`${location.pathname}#section-readme`),E==null||E.classList.add("UnitReadme--expanded")}function J(){var t;if(!location.hash)return;let n=document.getElementById(location.hash.slice(1)),e=(t=n==null?void 0:n.parentElement)==null?void 0:t.parentElement;(e==null?void 0:e.nodeName)==="DETAILS"&&(e.open=!0)}J();window.addEventListener("hashchange",()=>J());document.querySelectorAll(".js-buildContextSelect").forEach(n=>{n.addEventListener("change",e=>{window.location.search=`?GOOS=${e.target.value}`})});
 /*!
  * @license
  * Copyright 2019-2020 The Go Authors. All rights reserved.
diff --git a/static/frontend/unit/main/main.js.map b/static/frontend/unit/main/main.js.map
index 3e8f444..3e10286 100644
--- a/static/frontend/unit/main/main.js.map
+++ b/static/frontend/unit/main/main.js.map
@@ -1,7 +1,7 @@
 {
   "version": 3,
   "sources": ["../../../shared/playground/playground.ts", "../../../shared/analytics/analytics.ts", "../../../shared/keyboard/keyboard.ts", "../../../shared/jump/jump.ts", "../../../shared/outline/select.ts", "../../../shared/outline/tree.ts", "../../../shared/table/table.ts", "main.ts"],
-  "sourcesContent": ["/*!\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n// This file implements the playground implementation of the documentation\n// page. The playground involves a \"play\" button that allows you to open up\n// a new link to play.golang.org using the example code.\n\n// The CSS is in static/frontend/unit/main/_doc.css\n\n/**\n * CSS classes used by PlaygroundExampleController\n */\nconst PlayExampleClassName = {\n  PLAY_HREF: '.js-exampleHref',\n  PLAY_CONTAINER: '.js-exampleContainer',\n  EXAMPLE_INPUT: '.Documentation-exampleCode',\n  EXAMPLE_OUTPUT: '.Documentation-exampleOutput',\n  EXAMPLE_ERROR: '.Documentation-exampleError',\n  PLAY_BUTTON: '.Documentation-examplePlayButton',\n  SHARE_BUTTON: '.Documentation-exampleShareButton',\n  FORMAT_BUTTON: '.Documentation-exampleFormatButton',\n  RUN_BUTTON: '.Documentation-exampleRunButton',\n};\n\n/**\n * This controller enables playground examples to expand their dropdown or\n * generate shareable Go Playground URLs.\n */\nexport class PlaygroundExampleController {\n  /**\n   * The anchor tag used to identify the container with an example href.\n   * There is only one in an example container div.\n   */\n  private readonly anchorEl: HTMLAnchorElement | null;\n\n  /**\n   * The error element\n   */\n  private readonly errorEl: Element | null;\n\n  /**\n   * Buttons that redirect to an example's playground, this element\n   * only exists in executable examples.\n   */\n  private readonly playButtonEl: Element | null;\n  private readonly shareButtonEl: Element | null;\n\n  /**\n   * Button that formats the code in an example's playground.\n   */\n  private readonly formatButtonEl: Element | null;\n\n  /**\n   * Button that runs the code in an example's playground, this element\n   * only exists in executable examples.\n   */\n  private readonly runButtonEl: Element | null;\n\n  /**\n   * The executable code of an example.\n   */\n  private readonly inputEl: HTMLTextAreaElement | null;\n\n  /**\n   * The output of the given example code. This only exists if the\n   * author of the package provides an output for this example.\n   */\n  private readonly outputEl: Element | null;\n\n  /**\n   * @param exampleEl The div that contains playground content for the given example.\n   */\n  constructor(private readonly exampleEl: HTMLDetailsElement) {\n    this.exampleEl = exampleEl;\n    this.anchorEl = exampleEl.querySelector('a');\n    this.errorEl = exampleEl.querySelector(PlayExampleClassName.EXAMPLE_ERROR);\n    this.playButtonEl = exampleEl.querySelector(PlayExampleClassName.PLAY_BUTTON);\n    this.shareButtonEl = exampleEl.querySelector(PlayExampleClassName.SHARE_BUTTON);\n    this.formatButtonEl = exampleEl.querySelector(PlayExampleClassName.FORMAT_BUTTON);\n    this.runButtonEl = exampleEl.querySelector(PlayExampleClassName.RUN_BUTTON);\n    this.inputEl = this.makeTextArea(exampleEl.querySelector(PlayExampleClassName.EXAMPLE_INPUT));\n    this.outputEl = exampleEl.querySelector(PlayExampleClassName.EXAMPLE_OUTPUT);\n\n    // This is legacy listener to be replaced the listener for shareButtonEl.\n    this.playButtonEl?.addEventListener('click', () => this.handleShareButtonClick());\n    this.shareButtonEl?.addEventListener('click', () => this.handleShareButtonClick());\n    this.formatButtonEl?.addEventListener('click', () => this.handleFormatButtonClick());\n    this.runButtonEl?.addEventListener('click', () => this.handleRunButtonClick());\n\n    if (!this.inputEl) return;\n\n    this.resize();\n    this.inputEl.addEventListener('keyup', () => this.resize());\n    this.inputEl.addEventListener('keydown', e => this.onKeydown(e));\n  }\n\n  /**\n   * Replace the pre element with a textarea. The examples are initially rendered\n   * as pre elements so they're fully visible when JS is disabled.\n   */\n  makeTextArea(el: Element | null): HTMLTextAreaElement {\n    const t = document.createElement('textarea');\n    t.classList.add('Documentation-exampleCode', 'code');\n    t.spellcheck = false;\n    t.value = el?.textContent ?? '';\n    el?.parentElement?.replaceChild(t, el);\n    return t;\n  }\n\n  /**\n   * Retrieve the hash value of the anchor element.\n   */\n  getAnchorHash(): string | undefined {\n    return this.anchorEl?.hash;\n  }\n\n  /**\n   * Expands the current playground example.\n   */\n  expand(): void {\n    this.exampleEl.open = true;\n  }\n\n  /**\n   * Resizes the input element to accomodate the amount of text present.\n   */\n  private resize(): void {\n    if (this.inputEl?.value) {\n      const numLineBreaks = (this.inputEl.value.match(/\\n/g) || []).length;\n      // min-height + lines x line-height + padding + border\n      this.inputEl.style.height = `${(20 + numLineBreaks * 20 + 12 + 2) / 16}rem`;\n    }\n  }\n\n  /**\n   * Handler to override keyboard behavior in the playground's\n   * textarea element.\n   *\n   * Tab key inserts tabs into the example playground instead of\n   * switching to the next interactive element.\n   * @param e input element keyboard event.\n   */\n  private onKeydown(e: KeyboardEvent) {\n    if (e.key === 'Tab') {\n      document.execCommand('insertText', false, '\\t');\n      e.preventDefault();\n    }\n  }\n\n  /**\n   * Changes the text of the example's input box.\n   */\n  private setInputText(output: string) {\n    if (this.inputEl) {\n      this.inputEl.value = output;\n    }\n  }\n\n  /**\n   * Changes the text of the example's output box.\n   */\n  private setOutputText(output: string) {\n    if (this.outputEl) {\n      this.outputEl.textContent = output;\n    }\n  }\n\n  /**\n   * Sets the error message text and overwrites\n   * output box to indicate a failed response.\n   */\n  private setErrorText(err: string) {\n    if (this.errorEl) {\n      this.errorEl.textContent = err;\n    }\n    this.setOutputText('An error has occurred\u2026');\n  }\n\n  /**\n   * Opens a new window to play.golang.org using the\n   * example snippet's code in the playground.\n   */\n  private handleShareButtonClick() {\n    const PLAYGROUND_BASE_URL = 'https://play.golang.org/p/';\n\n    this.setOutputText('Waiting for remote server\u2026');\n\n    fetch('/play/share', {\n      method: 'POST',\n      body: this.inputEl?.value,\n    })\n      .then(res => res.text())\n      .then(shareId => {\n        const href = PLAYGROUND_BASE_URL + shareId;\n        this.setOutputText(`<a href=\"${href}\">${href}</a>`);\n        window.open(href);\n      })\n      .catch(err => {\n        this.setErrorText(err);\n      });\n  }\n\n  /**\n   * Runs gofmt on the example snippet in the playground.\n   */\n  private handleFormatButtonClick() {\n    this.setOutputText('Waiting for remote server\u2026');\n    const body = new FormData();\n    body.append('body', this.inputEl?.value ?? '');\n\n    fetch('/play/fmt', {\n      method: 'POST',\n      body: body,\n    })\n      .then(res => res.json())\n      .then(({ Body, Error }) => {\n        this.setOutputText(Error || 'Done.');\n        if (Body) {\n          this.setInputText(Body);\n          this.resize();\n        }\n      })\n      .catch(err => {\n        this.setErrorText(err);\n      });\n  }\n\n  /**\n   * Runs the code snippet in the example playground.\n   */\n  private handleRunButtonClick() {\n    this.setOutputText('Waiting for remote server\u2026');\n\n    fetch('/play/compile', {\n      method: 'POST',\n      body: JSON.stringify({ body: this.inputEl?.value, version: 2 }),\n    })\n      .then(res => res.json())\n      .then(async ({ Events, Errors }) => {\n        this.setOutputText(Errors || '');\n        for (const e of Events || []) {\n          this.setOutputText(e.Message);\n          await new Promise(resolve => setTimeout(resolve, e.Delay / 1000000));\n        }\n      })\n      .catch(err => {\n        this.setErrorText(err);\n      });\n  }\n}\n\nexport function initPlaygrounds(): void {\n  const exampleHashRegex = location.hash.match(/^#(example-.*)$/);\n  if (exampleHashRegex) {\n    const exampleHashEl = document.getElementById(exampleHashRegex[1]) as HTMLDetailsElement;\n    if (exampleHashEl) {\n      exampleHashEl.open = true;\n    }\n  }\n\n  // We use a spread operator to convert a nodelist into an array of elements.\n  const exampleHrefs = [\n    ...document.querySelectorAll<HTMLAnchorElement>(PlayExampleClassName.PLAY_HREF),\n  ];\n\n  /**\n   * Sometimes exampleHrefs and playContainers are in different order, so we\n   * find an exampleHref from a common hash.\n   * @param playContainer - playground container\n   */\n  const findExampleHash = (playContainer: PlaygroundExampleController) =>\n    exampleHrefs.find(ex => {\n      return ex.hash === playContainer.getAnchorHash();\n    });\n\n  for (const el of document.querySelectorAll(PlayExampleClassName.PLAY_CONTAINER)) {\n    // There should be the same amount of hrefs referencing examples as example containers.\n    const playContainer = new PlaygroundExampleController(el as HTMLDetailsElement);\n    const exampleHref = findExampleHash(playContainer);\n    if (exampleHref) {\n      exampleHref.addEventListener('click', () => {\n        playContainer.expand();\n      });\n    } else {\n      console.warn('example href not found');\n    }\n  }\n}\n", "interface TagManagerEvent {\n  /**\n   * event is the name of the event, used to filter events in\n   * Google Analytics.\n   */\n  event: string;\n\n  /**\n   * event_category is a name that you supply as a way to group objects\n   * that to analyze. Typically, you will use the same category name\n   * multiple times over related UI elements (buttons, links, etc).\n   */\n  event_category?: string;\n\n  /**\n   * event_action is used to name the type of event or interaction you\n   * want to measure for a particular web object. For example, with a\n   * single \"form\" category, you can analyze a number of specific events\n   * with this parameter, such as: form entered, form submitted.\n   */\n  event_action?: string;\n\n  /**\n   * event_label provide additional information for events that you want\n   * to analyze, such as the text label of a link.\n   */\n  event_label?: string;\n\n  /**\n   * gtm.start is used to initialize Google Tag Manager.\n   */\n  'gtm.start'?: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ndeclare global {\n  interface Window {\n    dataLayer?: (TagManagerEvent | VoidFunction)[];\n    ga?: unknown;\n  }\n}\n\n/**\n * track sends events to Google Tag Manager.\n */\nexport function track(\n  event: string | TagManagerEvent,\n  category?: string,\n  action?: string,\n  label?: string\n): void {\n  window.dataLayer ??= [];\n  if (typeof event === 'string') {\n    window.dataLayer.push({\n      event,\n      event_category: category,\n      event_action: action,\n      event_label: label,\n    });\n  } else {\n    window.dataLayer.push(event);\n  }\n}\n\n/**\n * func adds functions to run sequentionally after\n * Google Tag Manager is ready.\n */\nexport function func(fn: () => void): void {\n  window.dataLayer ??= [];\n  window.dataLayer.push(fn);\n}\n", "/*!\n * @license\n * Copyright 2019-2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { track } from '../analytics/analytics';\n\n/**\n * Options are keyhandler callback options.\n */\ninterface Options {\n  /**\n   * target is the element the key event should filter on. The\n   * default target is the document.\n   */\n  target?: Element;\n\n  /**\n   * withMeta specifies if the event callback should fire when\n   * the key is pressed with a meta key (ctrl, alt, etc). By\n   * default meta keypresses are ignored.\n   */\n  withMeta?: boolean;\n}\n\n/**\n * KeyHandler is the config for a keyboard event callback.\n */\ninterface KeyHandler extends Options {\n  description: string;\n  callback: (e: KeyboardEvent) => void;\n}\n\n/**\n * KeyboardController controls event callbacks for sitewide\n * keyboard events. Multiple callbacks can be registered for\n * a single key and by default the controller ignores events\n * for text input targets.\n */\nclass KeyboardController {\n  handlers: Record<string, Set<KeyHandler>>;\n\n  constructor() {\n    this.handlers = {};\n    document.addEventListener('keydown', e => this.handleKeyPress(e));\n  }\n\n  /**\n   * on registers keyboard event callbacks.\n   * @param key the key to register.\n   * @param description name of the event.\n   * @param callback event callback.\n   * @param options set target and withMeta options to override the default behaviors.\n   */\n  on(key: string, description: string, callback: (e: KeyboardEvent) => void, options?: Options) {\n    this.handlers[key] ??= new Set();\n    this.handlers[key].add({ description, callback, ...options });\n    return this;\n  }\n\n  private handleKeyPress(e: KeyboardEvent) {\n    for (const handler of this.handlers[e.key.toLowerCase()] ?? new Set()) {\n      if (handler.target && handler.target !== e.target) {\n        return;\n      }\n      const t = e.target as HTMLElement | null;\n      if (\n        !handler.target &&\n        (t?.tagName === 'INPUT' || t?.tagName === 'SELECT' || t?.tagName === 'TEXTAREA')\n      ) {\n        return;\n      }\n      if (t?.isContentEditable) {\n        return;\n      }\n      if (\n        (handler.withMeta && !(e.ctrlKey || e.metaKey)) ||\n        (!handler.withMeta && (e.ctrlKey || e.metaKey))\n      ) {\n        return;\n      }\n      track('keypress', 'hotkeys', `${e.key} pressed`, handler.description);\n      handler.callback(e);\n    }\n  }\n}\n\nexport const keyboard = new KeyboardController();\n", "/*!\n * @license\n * Copyright 2019-2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n// This file implements the behavior of the \"jump to symbol\" dialog for Go\n// package documentation, as well as the simple dialog that displays keyboard\n// shortcuts.\n\n// The DOM for the dialogs is at the bottom of static/frontend/unit/main/_modals.tmpl.\n// The CSS is in static/frontend/unit/main/_modals.css.\n\n// The dialog is activated by pressing the 'f' key. It presents a list\n// (#JumpDialog-list) of all Go symbols displayed in the documentation.\n// Entering text in the dialog's text box (#JumpDialog-filter) restricts the\n// list to symbols containing the text. Clicking on an symbol jumps to\n// its documentation.\n\n// This code is based on\n// https://go.googlesource.com/gddo/+/refs/heads/master/gddo-server/assets/site.js.\n// It was modified to remove the dependence on jquery and bootstrap.\n\nimport { keyboard } from '../keyboard/keyboard';\n\nconst jumpDialog = document.querySelector<HTMLDialogElement>('.JumpDialog');\nconst jumpBody = jumpDialog?.querySelector<HTMLDivElement>('.JumpDialog-body');\nconst jumpList = jumpDialog?.querySelector<HTMLDivElement>('.JumpDialog-list');\nconst jumpFilter = jumpDialog?.querySelector<HTMLInputElement>('.JumpDialog-input');\nconst doc = document.querySelector<HTMLDivElement>('.js-documentation');\n\ninterface JumpListItem {\n  link: HTMLAnchorElement;\n  name: string;\n  kind: string;\n  lower: string;\n}\n\nlet jumpListItems: JumpListItem[] | undefined; // All the symbols in the doc; computed only once.\n\n// collectJumpListItems returns a list of items, one for each symbol in the\n// documentation on the current page.\n//\n// It uses the data-kind attribute generated in the documentation HTML to find\n// the symbols and their id attributes.\n//\n// If there are no data-kind attributes, then we have older doc; fall back to\n// a less precise method.\nfunction collectJumpListItems() {\n  const items = [];\n  if (!doc) return;\n  for (const el of doc.querySelectorAll('[data-kind]')) {\n    items.push(newJumpListItem(el));\n  }\n\n  // Clicking on any of the links closes the dialog.\n  for (const item of items) {\n    item.link.addEventListener('click', function () {\n      jumpDialog?.close();\n    });\n  }\n  // Sort case-insensitively by symbol name.\n  items.sort(function (a, b) {\n    return a.lower.localeCompare(b.lower);\n  });\n  return items;\n}\n\n// newJumpListItem creates a new item for the DOM element el.\n// An item is an object with:\n// - name: the element's id (which is the symbol name)\n// - kind: the element's kind (function, variable, etc.),\n// - link: a link ('a' tag) to the element\n// - lower: the name in lower case, just for sorting\nfunction newJumpListItem(el: Element): JumpListItem {\n  const a = document.createElement('a');\n  const name = el.getAttribute('id');\n  a.setAttribute('href', '#' + name);\n  a.setAttribute('tabindex', '-1');\n  a.setAttribute('data-gtmc', 'jump to link');\n  const kind = el.getAttribute('data-kind');\n  return {\n    link: a,\n    name: name ?? '',\n    kind: kind ?? '',\n    lower: name?.toLowerCase() ?? '', // for sorting\n  };\n}\n\nlet lastFilterValue: string; // The last contents of the filter text box.\nlet activeJumpItem = -1; // The index of the currently active item in the list.\n\n// updateJumpList sets the elements of the dialog list to\n// everything whose name contains filter.\nfunction updateJumpList(filter: string) {\n  lastFilterValue = filter;\n  if (!jumpListItems) {\n    jumpListItems = collectJumpListItems();\n  }\n  setActiveJumpItem(-1);\n\n  // Remove all children from list.\n  while (jumpList?.firstChild) {\n    jumpList.firstChild.remove();\n  }\n\n  if (filter) {\n    // A filter is set. We treat the filter as a substring that can appear in\n    // an item name (case insensitive), and find the following matches - in\n    // order of priority:\n    //\n    // 1. Exact matches (the filter matches the item's name exactly)\n    // 2. Prefix matches (the item's name starts with filter)\n    // 3. Infix matches (the filter is a substring of the item's name)\n    const filterLowerCase = filter.toLowerCase();\n\n    const exactMatches = [];\n    const prefixMatches = [];\n    const infixMatches = [];\n\n    // makeLinkHtml creates the link name HTML for a list item. item is the DOM\n    // item. item.name.substr(boldStart, boldEnd) will be bolded.\n    const makeLinkHtml = (item: JumpListItem, boldStart: number, boldEnd: number) => {\n      return (\n        item.name.substring(0, boldStart) +\n        '<b>' +\n        item.name.substring(boldStart, boldEnd) +\n        '</b>' +\n        item.name.substring(boldEnd)\n      );\n    };\n\n    for (const item of jumpListItems ?? []) {\n      const nameLowerCase = item.name.toLowerCase();\n\n      if (nameLowerCase === filterLowerCase) {\n        item.link.innerHTML = makeLinkHtml(item, 0, item.name.length);\n        exactMatches.push(item);\n      } else if (nameLowerCase.startsWith(filterLowerCase)) {\n        item.link.innerHTML = makeLinkHtml(item, 0, filter.length);\n        prefixMatches.push(item);\n      } else {\n        const index = nameLowerCase.indexOf(filterLowerCase);\n        if (index > -1) {\n          item.link.innerHTML = makeLinkHtml(item, index, index + filter.length);\n          infixMatches.push(item);\n        }\n      }\n    }\n\n    for (const item of exactMatches.concat(prefixMatches).concat(infixMatches)) {\n      jumpList?.appendChild(item.link);\n    }\n  } else {\n    if (!jumpListItems || jumpListItems.length === 0) {\n      const msg = document.createElement('i');\n      msg.innerHTML = 'There are no symbols on this page.';\n      jumpList?.appendChild(msg);\n    }\n    // No filter set; display all items in their existing order.\n    for (const item of jumpListItems ?? []) {\n      item.link.innerHTML = item.name + ' <i>' + item.kind + '</i>';\n      jumpList?.appendChild(item.link);\n    }\n  }\n\n  if (jumpBody) {\n    jumpBody.scrollTop = 0;\n  }\n  if (jumpListItems?.length && jumpList && jumpList.children.length > 0) {\n    setActiveJumpItem(0);\n  }\n}\n\n// Set the active jump item to n.\nfunction setActiveJumpItem(n: number) {\n  const cs = jumpList?.children as HTMLCollectionOf<HTMLElement> | null | undefined;\n  if (!cs || !jumpBody) {\n    return;\n  }\n  if (activeJumpItem >= 0) {\n    cs[activeJumpItem].classList.remove('JumpDialog-active');\n  }\n  if (n >= cs.length) {\n    n = cs.length - 1;\n  }\n  if (n >= 0) {\n    cs[n].classList.add('JumpDialog-active');\n\n    // Scroll so the active item is visible.\n    // For some reason cs[n].scrollIntoView() doesn't behave as I'd expect:\n    // it moves the entire dialog box in the viewport.\n\n    // Get the top and bottom of the active item relative to jumpBody.\n    const activeTop = cs[n].offsetTop - cs[0].offsetTop;\n    const activeBottom = activeTop + cs[n].clientHeight;\n    if (activeTop < jumpBody.scrollTop) {\n      // Off the top; scroll up.\n      jumpBody.scrollTop = activeTop;\n    } else if (activeBottom > jumpBody.scrollTop + jumpBody.clientHeight) {\n      // Off the bottom; scroll down.\n      jumpBody.scrollTop = activeBottom - jumpBody.clientHeight;\n    }\n  }\n  activeJumpItem = n;\n}\n\n// Increment the activeJumpItem by delta.\nfunction incActiveJumpItem(delta: number) {\n  if (activeJumpItem < 0) {\n    return;\n  }\n  let n = activeJumpItem + delta;\n  if (n < 0) {\n    n = 0;\n  }\n  setActiveJumpItem(n);\n}\n\nexport function initModals(): void {\n  // Pressing a key in the filter updates the list (if the filter actually changed).\n  jumpFilter?.addEventListener('keyup', function () {\n    if (jumpFilter.value.toUpperCase() != lastFilterValue.toUpperCase()) {\n      updateJumpList(jumpFilter.value);\n    }\n  });\n\n  // Pressing enter in the filter selects the first element in the list.\n  jumpFilter?.addEventListener('keydown', function (event) {\n    const upArrow = 38;\n    const downArrow = 40;\n    const enterKey = 13;\n    switch (event.which) {\n      case upArrow:\n        incActiveJumpItem(-1);\n        event.preventDefault();\n        break;\n      case downArrow:\n        incActiveJumpItem(1);\n        event.preventDefault();\n        break;\n      case enterKey:\n        if (activeJumpItem >= 0) {\n          if (jumpList) {\n            (jumpList.children[activeJumpItem] as HTMLElement).click();\n            event.preventDefault();\n          }\n        }\n        break;\n    }\n  });\n\n  const shortcutsDialog = document.querySelector<HTMLDialogElement>('.ShortcutsDialog');\n\n  // - Pressing 'f' or 'F' opens the jump-to-symbol dialog.\n  // - Pressing '?' opens up the shortcut dialog.\n  // Ignore a keypress if a dialog is already open, or if it is pressed on a\n  // component that wants to consume it.\n  keyboard\n    .on('f', 'open jump to modal', e => {\n      if (jumpDialog?.open || shortcutsDialog?.open) {\n        return;\n      }\n      e.preventDefault();\n      if (jumpFilter) {\n        jumpFilter.value = '';\n      }\n      jumpDialog?.showModal();\n      jumpFilter?.focus();\n      updateJumpList('');\n    })\n    .on('?', 'open shortcuts modal', () => {\n      if (jumpDialog?.open || shortcutsDialog?.open) {\n        return;\n      }\n      shortcutsDialog?.showModal();\n    });\n\n  const jumpOutlineInput = document.querySelector('.js-jumpToInput');\n  if (jumpOutlineInput) {\n    jumpOutlineInput.addEventListener('click', () => {\n      if (jumpFilter) {\n        jumpFilter.value = '';\n      }\n      updateJumpList('');\n    });\n  }\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { TreeNavController } from './tree.js';\n\nexport class SelectNavController {\n  constructor(private el: Element) {\n    this.el.addEventListener('change', e => {\n      const target = e.target as HTMLSelectElement;\n      let href = target.value;\n      if (!target.value.startsWith('/')) {\n        href = '/' + href;\n      }\n      window.location.href = href;\n    });\n  }\n}\n\nexport function makeSelectNav(tree: TreeNavController): HTMLLabelElement {\n  const label = document.createElement('label');\n  label.classList.add('go-Label');\n  label.setAttribute('aria-label', 'Menu');\n  const select = document.createElement('select');\n  select.classList.add('go-Select', 'js-selectNav');\n  label.appendChild(select);\n  const outline = document.createElement('optgroup');\n  outline.label = 'Outline';\n  select.appendChild(outline);\n  const groupMap: Record<string, HTMLOptGroupElement> = {};\n  let group: HTMLOptGroupElement;\n  for (const t of tree.treeitems) {\n    if (Number(t.depth) > 4) continue;\n    if (t.groupTreeitem) {\n      group = groupMap[t.groupTreeitem.label];\n      if (!group) {\n        group = groupMap[t.groupTreeitem.label] = document.createElement('optgroup');\n        group.label = t.groupTreeitem.label;\n        select.appendChild(group);\n      }\n    } else {\n      group = outline;\n    }\n    const o = document.createElement('option');\n    o.label = t.label;\n    o.textContent = t.label;\n    o.value = (t.el as HTMLAnchorElement).href.replace(window.location.origin, '').replace('/', '');\n    group.appendChild(o);\n  }\n  tree.addObserver(t => {\n    const hash = (t.el as HTMLAnchorElement).hash;\n    const value = select.querySelector<HTMLOptionElement>(`[value$=\"${hash}\"]`)?.value;\n    if (value) {\n      select.value = value;\n    }\n  }, 50);\n  return label;\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * TreeNavController is the navigation tree component of the documentation page.\n * It adds accessiblity attributes to a tree, observes the heading elements\n * focus the topmost link for headings visible on the page, and implements the\n * WAI-ARIA Treeview Design Pattern with full\n * [keyboard support](https://www.w3.org/TR/wai-aria-practices/examples/treeview/treeview-2/treeview-2a.html#kbd_label).\n */\nexport class TreeNavController {\n  treeitems: TreeItem[];\n\n  /**\n   * firstChars is the first character of each treeitem in the same order\n   * as this.treeitems. We use this array to set focus by character when\n   * navigating the tree with a keyboard.\n   */\n  private firstChars: string[];\n  private firstTreeitem: TreeItem | null;\n  private lastTreeitem: TreeItem | null;\n  private observerCallbacks: ((t: TreeItem) => void)[];\n\n  constructor(private el: HTMLElement) {\n    this.treeitems = [];\n    this.firstChars = [];\n    this.firstTreeitem = null;\n    this.lastTreeitem = null;\n    this.observerCallbacks = [];\n    this.init();\n  }\n\n  private init(): void {\n    this.handleResize();\n    window.addEventListener('resize', this.handleResize);\n    this.findTreeItems();\n    this.updateVisibleTreeitems();\n    this.observeTargets();\n    if (this.firstTreeitem) {\n      this.firstTreeitem.el.tabIndex = 0;\n    }\n  }\n\n  private handleResize = (): void => {\n    this.el.style.setProperty('--js-tree-height', '100vh');\n    this.el.style.setProperty('--js-tree-height', this.el.clientHeight + 'px');\n  };\n\n  private observeTargets() {\n    this.addObserver(treeitem => {\n      this.expandTreeitem(treeitem);\n      this.setSelected(treeitem);\n      // TODO: Fix scroll issue in https://golang.org/issue/47450.\n      // treeitem.el.scrollIntoView({ block: 'nearest' });\n    });\n\n    const targets = new Map<string, boolean>();\n    const observer = new IntersectionObserver(\n      entries => {\n        for (const entry of entries) {\n          targets.set(entry.target.id, entry.isIntersecting || entry.intersectionRatio === 1);\n        }\n        for (const [id, isIntersecting] of targets) {\n          if (isIntersecting) {\n            const active = this.treeitems.find(t =>\n              (t.el as HTMLAnchorElement)?.href.endsWith(`#${id}`)\n            );\n            if (active) {\n              for (const fn of this.observerCallbacks) {\n                fn(active);\n              }\n            }\n            break;\n          }\n        }\n      },\n      {\n        threshold: 1.0,\n        rootMargin: '-60px 0px 0px 0px',\n      }\n    );\n\n    for (const href of this.treeitems.map(t => t.el.getAttribute('href'))) {\n      if (href) {\n        const id = href.replace(window.location.origin, '').replace('/', '').replace('#', '');\n        const target = document.getElementById(id);\n        if (target) {\n          observer.observe(target);\n        }\n      }\n    }\n  }\n\n  addObserver(fn: (t: TreeItem) => void, delay = 200): void {\n    this.observerCallbacks.push(debounce(fn, delay));\n  }\n\n  setFocusToNextItem(currentItem: TreeItem): void {\n    let nextItem = null;\n    for (let i = currentItem.index + 1; i < this.treeitems.length; i++) {\n      const ti = this.treeitems[i];\n      if (ti.isVisible) {\n        nextItem = ti;\n        break;\n      }\n    }\n    if (nextItem) {\n      this.setFocusToItem(nextItem);\n    }\n  }\n\n  setFocusToPreviousItem(currentItem: TreeItem): void {\n    let prevItem = null;\n    for (let i = currentItem.index - 1; i > -1; i--) {\n      const ti = this.treeitems[i];\n      if (ti.isVisible) {\n        prevItem = ti;\n        break;\n      }\n    }\n    if (prevItem) {\n      this.setFocusToItem(prevItem);\n    }\n  }\n\n  setFocusToParentItem(currentItem: TreeItem): void {\n    if (currentItem.groupTreeitem) {\n      this.setFocusToItem(currentItem.groupTreeitem);\n    }\n  }\n\n  setFocusToFirstItem(): void {\n    this.firstTreeitem && this.setFocusToItem(this.firstTreeitem);\n  }\n\n  setFocusToLastItem(): void {\n    this.lastTreeitem && this.setFocusToItem(this.lastTreeitem);\n  }\n\n  setSelected(currentItem: TreeItem): void {\n    for (const l1 of this.el.querySelectorAll('[aria-expanded=\"true\"]')) {\n      if (l1 === currentItem.el) continue;\n      if (!l1.nextElementSibling?.contains(currentItem.el)) {\n        l1.setAttribute('aria-expanded', 'false');\n      }\n    }\n    for (const l1 of this.el.querySelectorAll('[aria-selected]')) {\n      if (l1 !== currentItem.el) {\n        l1.setAttribute('aria-selected', 'false');\n      }\n    }\n    currentItem.el.setAttribute('aria-selected', 'true');\n    this.updateVisibleTreeitems();\n    this.setFocusToItem(currentItem, false);\n  }\n\n  expandTreeitem(treeitem: TreeItem): void {\n    let currentItem: TreeItem | null = treeitem;\n    while (currentItem) {\n      if (currentItem.isExpandable) {\n        currentItem.el.setAttribute('aria-expanded', 'true');\n      }\n      currentItem = currentItem.groupTreeitem;\n    }\n    this.updateVisibleTreeitems();\n  }\n\n  expandAllSiblingItems(currentItem: TreeItem): void {\n    for (const ti of this.treeitems) {\n      if (ti.groupTreeitem === currentItem.groupTreeitem && ti.isExpandable) {\n        this.expandTreeitem(ti);\n      }\n    }\n  }\n\n  collapseTreeitem(currentItem: TreeItem): void {\n    let groupTreeitem = null;\n\n    if (currentItem.isExpanded()) {\n      groupTreeitem = currentItem;\n    } else {\n      groupTreeitem = currentItem.groupTreeitem;\n    }\n\n    if (groupTreeitem) {\n      groupTreeitem.el.setAttribute('aria-expanded', 'false');\n      this.updateVisibleTreeitems();\n      this.setFocusToItem(groupTreeitem);\n    }\n  }\n\n  setFocusByFirstCharacter(currentItem: TreeItem, char: string): void {\n    let start: number, index: number;\n    char = char.toLowerCase();\n\n    // Get start index for search based on position of currentItem\n    start = currentItem.index + 1;\n    if (start === this.treeitems.length) {\n      start = 0;\n    }\n\n    // Check remaining slots in the menu\n    index = this.getIndexFirstChars(start, char);\n\n    // If not found in remaining slots, check from beginning\n    if (index === -1) {\n      index = this.getIndexFirstChars(0, char);\n    }\n\n    // If match was found...\n    if (index > -1) {\n      this.setFocusToItem(this.treeitems[index]);\n    }\n  }\n\n  private findTreeItems() {\n    const findItems = (el: HTMLElement, group: TreeItem | null) => {\n      let ti = group;\n      let curr = el.firstElementChild as HTMLElement;\n      while (curr) {\n        if (curr.tagName === 'A' || curr.tagName === 'SPAN') {\n          ti = new TreeItem(curr, this, group);\n          this.treeitems.push(ti);\n          this.firstChars.push(ti.label.substring(0, 1).toLowerCase());\n        }\n        if (curr.firstElementChild) {\n          findItems(curr, ti);\n        }\n        curr = curr.nextElementSibling as HTMLElement;\n      }\n    };\n    findItems(this.el as HTMLElement, null);\n    this.treeitems.map((ti, idx) => (ti.index = idx));\n  }\n\n  private updateVisibleTreeitems(): void {\n    this.firstTreeitem = this.treeitems[0];\n\n    for (const ti of this.treeitems) {\n      let parent = ti.groupTreeitem;\n      ti.isVisible = true;\n      while (parent && parent.el !== this.el) {\n        if (!parent.isExpanded()) {\n          ti.isVisible = false;\n        }\n        parent = parent.groupTreeitem;\n      }\n      if (ti.isVisible) {\n        this.lastTreeitem = ti;\n      }\n    }\n  }\n\n  private setFocusToItem(treeitem: TreeItem, focusEl = true) {\n    treeitem.el.tabIndex = 0;\n    if (focusEl) {\n      treeitem.el.focus();\n    }\n    for (const ti of this.treeitems) {\n      if (ti !== treeitem) {\n        ti.el.tabIndex = -1;\n      }\n    }\n  }\n\n  private getIndexFirstChars(startIndex: number, char: string): number {\n    for (let i = startIndex; i < this.firstChars.length; i++) {\n      if (this.treeitems[i].isVisible && char === this.firstChars[i]) {\n        return i;\n      }\n    }\n    return -1;\n  }\n}\n\nclass TreeItem {\n  el: HTMLElement;\n  groupTreeitem: TreeItem | null;\n  label: string;\n  isExpandable: boolean;\n  isVisible: boolean;\n  depth: number;\n  index: number;\n\n  private tree: TreeNavController;\n  private isInGroup: boolean;\n\n  constructor(el: HTMLElement, treeObj: TreeNavController, group: TreeItem | null) {\n    el.tabIndex = -1;\n    this.el = el;\n    this.groupTreeitem = group;\n    this.label = el.textContent?.trim() ?? '';\n    this.tree = treeObj;\n    this.depth = (group?.depth || 0) + 1;\n    this.index = 0;\n\n    const parent = el.parentElement;\n    if (parent?.tagName.toLowerCase() === 'li') {\n      parent?.setAttribute('role', 'none');\n    }\n    el.setAttribute('aria-level', this.depth + '');\n    if (el.getAttribute('aria-label')) {\n      this.label = el?.getAttribute('aria-label')?.trim() ?? '';\n    }\n\n    this.isExpandable = false;\n    this.isVisible = false;\n    this.isInGroup = !!group;\n\n    let curr = el.nextElementSibling;\n    while (curr) {\n      if (curr.tagName.toLowerCase() == 'ul') {\n        const groupId = `${group?.label ?? ''} nav group ${this.label}`.replace(/[\\W_]+/g, '_');\n        el.setAttribute('aria-owns', groupId);\n        el.setAttribute('aria-expanded', 'false');\n        curr.setAttribute('role', 'group');\n        curr.setAttribute('id', groupId);\n        this.isExpandable = true;\n        break;\n      }\n\n      curr = curr.nextElementSibling;\n    }\n    this.init();\n  }\n\n  private init() {\n    this.el.tabIndex = -1;\n    if (!this.el.getAttribute('role')) {\n      this.el.setAttribute('role', 'treeitem');\n    }\n    this.el.addEventListener('keydown', this.handleKeydown.bind(this));\n    this.el.addEventListener('click', this.handleClick.bind(this));\n    this.el.addEventListener('focus', this.handleFocus.bind(this));\n    this.el.addEventListener('blur', this.handleBlur.bind(this));\n  }\n\n  isExpanded() {\n    if (this.isExpandable) {\n      return this.el.getAttribute('aria-expanded') === 'true';\n    }\n\n    return false;\n  }\n\n  isSelected() {\n    return this.el.getAttribute('aria-selected') === 'true';\n  }\n\n  private handleClick(event: MouseEvent) {\n    // only process click events that directly happened on this treeitem\n    if (event.target !== this.el && event.target !== this.el.firstElementChild) {\n      return;\n    }\n    if (this.isExpandable) {\n      if (this.isExpanded() && this.isSelected()) {\n        this.tree.collapseTreeitem(this);\n      } else {\n        this.tree.expandTreeitem(this);\n      }\n      event.stopPropagation();\n    }\n    this.tree.setSelected(this);\n  }\n\n  private handleFocus() {\n    let el = this.el;\n    if (this.isExpandable) {\n      el = (el.firstElementChild as HTMLElement) ?? el;\n    }\n    el.classList.add('focus');\n  }\n\n  private handleBlur() {\n    let el = this.el;\n    if (this.isExpandable) {\n      el = (el.firstElementChild as HTMLElement) ?? el;\n    }\n    el.classList.remove('focus');\n  }\n\n  private handleKeydown(event: KeyboardEvent) {\n    if (event.altKey || event.ctrlKey || event.metaKey) {\n      return;\n    }\n\n    let captured = false;\n    switch (event.key) {\n      case ' ':\n      case 'Enter':\n        if (this.isExpandable) {\n          if (this.isExpanded() && this.isSelected()) {\n            this.tree.collapseTreeitem(this);\n          } else {\n            this.tree.expandTreeitem(this);\n          }\n          captured = true;\n        } else {\n          event.stopPropagation();\n        }\n        this.tree.setSelected(this);\n        break;\n\n      case 'ArrowUp':\n        this.tree.setFocusToPreviousItem(this);\n        captured = true;\n        break;\n\n      case 'ArrowDown':\n        this.tree.setFocusToNextItem(this);\n        captured = true;\n        break;\n\n      case 'ArrowRight':\n        if (this.isExpandable) {\n          if (this.isExpanded()) {\n            this.tree.setFocusToNextItem(this);\n          } else {\n            this.tree.expandTreeitem(this);\n          }\n        }\n        captured = true;\n        break;\n\n      case 'ArrowLeft':\n        if (this.isExpandable && this.isExpanded()) {\n          this.tree.collapseTreeitem(this);\n          captured = true;\n        } else {\n          if (this.isInGroup) {\n            this.tree.setFocusToParentItem(this);\n            captured = true;\n          }\n        }\n        break;\n\n      case 'Home':\n        this.tree.setFocusToFirstItem();\n        captured = true;\n        break;\n\n      case 'End':\n        this.tree.setFocusToLastItem();\n        captured = true;\n        break;\n\n      default:\n        if (event.key.length === 1 && event.key.match(/\\S/)) {\n          if (event.key == '*') {\n            this.tree.expandAllSiblingItems(this);\n          } else {\n            this.tree.setFocusByFirstCharacter(this, event.key);\n          }\n          captured = true;\n        }\n        break;\n    }\n\n    if (captured) {\n      event.stopPropagation();\n      event.preventDefault();\n    }\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction debounce<T extends (...args: any[]) => any>(func: T, wait: number) {\n  let timeout: ReturnType<typeof setTimeout> | null;\n  return (...args: Parameters<T>) => {\n    const later = () => {\n      timeout = null;\n      func(...args);\n    };\n    if (timeout) {\n      clearTimeout(timeout);\n    }\n    timeout = setTimeout(later, wait);\n  };\n}\n", "/*!\n * @license\n * Copyright 2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * Controller for a table element with expandable rows. Adds event listeners to\n * a toggle within a table row that controls visiblity of additional related\n * rows in the table.\n *\n * @example\n * ```typescript\n * import {ExpandableRowsTableController} from '/static/js/table';\n *\n * const el = document .querySelector<HTMLTableElement>('.js-myTableElement')\n * new ExpandableRowsTableController(el));\n * ```\n */\nexport class ExpandableRowsTableController {\n  private rows: HTMLTableRowElement[];\n  private toggles: HTMLButtonElement[];\n\n  /**\n   * Create a table controller.\n   * @param table - The table element to which the controller binds.\n   */\n  constructor(private table: HTMLTableElement, private toggleAll?: HTMLButtonElement | null) {\n    this.rows = Array.from(table.querySelectorAll<HTMLTableRowElement>('[data-aria-controls]'));\n    this.toggles = Array.from(this.table.querySelectorAll('[aria-expanded]'));\n    this.setAttributes();\n    this.attachEventListeners();\n    this.update();\n  }\n\n  /**\n   * setAttributes sets data-aria-* and data-id attributes to regular\n   * html attributes as a workaround for limitations from safehtml.\n   */\n  private setAttributes() {\n    for (const a of ['data-aria-controls', 'data-aria-labelledby', 'data-id']) {\n      this.table.querySelectorAll(`[${a}]`).forEach(t => {\n        t.setAttribute(a.replace('data-', ''), t.getAttribute(a) ?? '');\n        t.removeAttribute(a);\n      });\n    }\n  }\n\n  private attachEventListeners() {\n    this.rows.forEach(t => {\n      t.addEventListener('click', e => {\n        this.handleToggleClick(e);\n      });\n    });\n    this.toggleAll?.addEventListener('click', () => {\n      this.expandAllItems();\n    });\n\n    document.addEventListener('keydown', e => {\n      if ((e.ctrlKey || e.metaKey) && e.key === 'f') {\n        this.expandAllItems();\n      }\n    });\n  }\n\n  private handleToggleClick(e: MouseEvent) {\n    let target = e.currentTarget as HTMLTableRowElement | null;\n    if (!target?.hasAttribute('aria-expanded')) {\n      target = this.table.querySelector(\n        `button[aria-controls=\"${target?.getAttribute('aria-controls')}\"]`\n      );\n    }\n    const isExpanded = target?.getAttribute('aria-expanded') === 'true';\n    target?.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');\n    e.stopPropagation();\n    this.update();\n  }\n\n  expandAllItems = (): void => {\n    this.toggles.map(t => t.setAttribute('aria-expanded', 'true'));\n    this.update();\n  };\n\n  private collapseAllItems = () => {\n    this.toggles.map(t => t.setAttribute('aria-expanded', 'false'));\n    this.update();\n  };\n\n  private update = () => {\n    this.updateVisibleItems();\n    setTimeout(() => this.updateGlobalToggle());\n  };\n\n  private updateVisibleItems() {\n    this.rows.map(t => {\n      const isExpanded = t?.getAttribute('aria-expanded') === 'true';\n      const rowIds = t?.getAttribute('aria-controls')?.trimEnd().split(' ');\n      rowIds?.map(id => {\n        const target = document.getElementById(`${id}`);\n        if (isExpanded) {\n          target?.classList.add('visible');\n          target?.classList.remove('hidden');\n        } else {\n          target?.classList.add('hidden');\n          target?.classList.remove('visible');\n        }\n      });\n    });\n  }\n\n  private updateGlobalToggle() {\n    if (!this.toggleAll) return;\n    if (this.rows.some(t => t.hasAttribute('aria-expanded'))) {\n      this.toggleAll.style.display = 'block';\n    }\n    const someCollapsed = this.toggles.some(el => el.getAttribute('aria-expanded') === 'false');\n    if (someCollapsed) {\n      this.toggleAll.innerText = 'Expand all';\n      this.toggleAll.onclick = this.expandAllItems;\n    } else {\n      this.toggleAll.innerText = 'Collapse all';\n      this.toggleAll.onclick = this.collapseAllItems;\n    }\n  }\n}\n", "import { initPlaygrounds } from 'static/shared/playground/playground';\nimport { initModals } from 'static/shared/jump/jump';\nimport { SelectNavController, makeSelectNav } from 'static/shared/outline/select';\nimport { TreeNavController } from 'static/shared/outline/tree';\nimport { ExpandableRowsTableController } from 'static/shared/table/table';\n\ninitModals();\ninitPlaygrounds();\n\nconst directories = document.querySelector<HTMLTableElement>('.js-expandableTable');\nif (directories) {\n  const table = new ExpandableRowsTableController(\n    directories,\n    document.querySelector<HTMLButtonElement>('.js-expandAllDirectories')\n  );\n  // Expand directories on page load with expand-directories query param.\n  if (window.location.search.includes('expand-directories')) {\n    table.expandAllItems();\n  }\n}\n\nconst treeEl = document.querySelector<HTMLElement>('.js-tree');\nif (treeEl) {\n  const treeCtrl = new TreeNavController(treeEl);\n  const select = makeSelectNav(treeCtrl);\n  const mobileNav = document.querySelector('.js-mainNavMobile');\n  if (mobileNav && mobileNav.firstElementChild) {\n    mobileNav?.replaceChild(select, mobileNav.firstElementChild);\n  }\n  if (select.firstElementChild) {\n    new SelectNavController(select.firstElementChild);\n  }\n}\n\n/**\n * Event handlers for expanding and collapsing the readme section.\n */\nconst readme = document.querySelector('.js-readme');\nconst readmeContent = document.querySelector('.js-readmeContent');\nconst readmeOutline = document.querySelector('.js-readmeOutline');\nconst readmeExpand = document.querySelectorAll('.js-readmeExpand');\nconst readmeCollapse = document.querySelector('.js-readmeCollapse');\nconst mobileNavSelect = document.querySelector<HTMLSelectElement>('.DocNavMobile-select');\nif (readme && readmeContent && readmeOutline && readmeExpand.length && readmeCollapse) {\n  if (window.location.hash.includes('readme')) {\n    expandReadme();\n  }\n  mobileNavSelect?.addEventListener('change', e => {\n    if ((e.target as HTMLSelectElement).value.startsWith('readme-')) {\n      expandReadme();\n    }\n  });\n  readmeExpand.forEach(el =>\n    el.addEventListener('click', e => {\n      e.preventDefault();\n      expandReadme();\n      readme.scrollIntoView();\n    })\n  );\n  readmeCollapse.addEventListener('click', e => {\n    e.preventDefault();\n    readme.classList.remove('UnitReadme--expanded');\n    if (readmeExpand[1]) {\n      readmeExpand[1].scrollIntoView({ block: 'center' });\n    }\n  });\n  readmeContent.addEventListener('keyup', () => {\n    expandReadme();\n  });\n  readmeContent.addEventListener('click', () => {\n    expandReadme();\n  });\n  readmeOutline.addEventListener('click', () => {\n    expandReadme();\n  });\n  document.addEventListener('keydown', e => {\n    if ((e.ctrlKey || e.metaKey) && e.key === 'f') {\n      expandReadme();\n    }\n  });\n}\n\n/**\n * expandReadme expands the readme and adds the section-readme hash to the\n * URL so it stays expanded when navigating back from an external link.\n */\nfunction expandReadme() {\n  history.replaceState(null, '', `${location.pathname}#section-readme`);\n  readme?.classList.add('UnitReadme--expanded');\n}\n\n/**\n * Expand details items that are focused. This will expand\n * deprecated symbols when they are navigated to from the index\n * or a direct link.\n */\nfunction openDeprecatedSymbol() {\n  if (!location.hash) return;\n  const heading = document.getElementById(location.hash.slice(1));\n  const grandParent = heading?.parentElement?.parentElement as HTMLDetailsElement | null;\n  if (grandParent?.nodeName === 'DETAILS') {\n    grandParent.open = true;\n  }\n}\nopenDeprecatedSymbol();\nwindow.addEventListener('hashchange', () => openDeprecatedSymbol());\n\n/**\n * Listen for changes in the build context dropdown.\n */\ndocument.querySelectorAll('.js-buildContextSelect').forEach(el => {\n  el.addEventListener('change', e => {\n    window.location.search = `?GOOS=${(e.target as HTMLSelectElement).value}`;\n  });\n});\n"],
-  "mappings": "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",
+  "sourcesContent": ["/*!\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n// This file implements the playground implementation of the documentation\n// page. The playground involves a \"play\" button that allows you to open up\n// a new link to play.golang.org using the example code.\n\n// The CSS is in static/frontend/unit/main/_doc.css\n\n/**\n * CSS classes used by PlaygroundExampleController\n */\nconst PlayExampleClassName = {\n  PLAY_HREF: '.js-exampleHref',\n  PLAY_CONTAINER: '.js-exampleContainer',\n  EXAMPLE_INPUT: '.Documentation-exampleCode',\n  EXAMPLE_OUTPUT: '.Documentation-exampleOutput',\n  EXAMPLE_ERROR: '.Documentation-exampleError',\n  PLAY_BUTTON: '.Documentation-examplePlayButton',\n  SHARE_BUTTON: '.Documentation-exampleShareButton',\n  FORMAT_BUTTON: '.Documentation-exampleFormatButton',\n  RUN_BUTTON: '.Documentation-exampleRunButton',\n};\n\n/**\n * This controller enables playground examples to expand their dropdown or\n * generate shareable Go Playground URLs.\n */\nexport class PlaygroundExampleController {\n  /**\n   * The anchor tag used to identify the container with an example href.\n   * There is only one in an example container div.\n   */\n  private readonly anchorEl: HTMLAnchorElement | null;\n\n  /**\n   * The error element\n   */\n  private readonly errorEl: Element | null;\n\n  /**\n   * Buttons that redirect to an example's playground, this element\n   * only exists in executable examples.\n   */\n  private readonly playButtonEl: Element | null;\n  private readonly shareButtonEl: Element | null;\n\n  /**\n   * Button that formats the code in an example's playground.\n   */\n  private readonly formatButtonEl: Element | null;\n\n  /**\n   * Button that runs the code in an example's playground, this element\n   * only exists in executable examples.\n   */\n  private readonly runButtonEl: Element | null;\n\n  /**\n   * The executable code of an example.\n   */\n  private readonly inputEl: HTMLTextAreaElement | null;\n\n  /**\n   * The output of the given example code. This only exists if the\n   * author of the package provides an output for this example.\n   */\n  private readonly outputEl: Element | null;\n\n  /**\n   * @param exampleEl The div that contains playground content for the given example.\n   */\n  constructor(private readonly exampleEl: HTMLDetailsElement) {\n    this.exampleEl = exampleEl;\n    this.anchorEl = exampleEl.querySelector('a');\n    this.errorEl = exampleEl.querySelector(PlayExampleClassName.EXAMPLE_ERROR);\n    this.playButtonEl = exampleEl.querySelector(PlayExampleClassName.PLAY_BUTTON);\n    this.shareButtonEl = exampleEl.querySelector(PlayExampleClassName.SHARE_BUTTON);\n    this.formatButtonEl = exampleEl.querySelector(PlayExampleClassName.FORMAT_BUTTON);\n    this.runButtonEl = exampleEl.querySelector(PlayExampleClassName.RUN_BUTTON);\n    this.inputEl = this.makeTextArea(exampleEl.querySelector(PlayExampleClassName.EXAMPLE_INPUT));\n    this.outputEl = exampleEl.querySelector(PlayExampleClassName.EXAMPLE_OUTPUT);\n\n    // This is legacy listener to be replaced the listener for shareButtonEl.\n    this.playButtonEl?.addEventListener('click', () => this.handleShareButtonClick());\n    this.shareButtonEl?.addEventListener('click', () => this.handleShareButtonClick());\n    this.formatButtonEl?.addEventListener('click', () => this.handleFormatButtonClick());\n    this.runButtonEl?.addEventListener('click', () => this.handleRunButtonClick());\n\n    if (!this.inputEl) return;\n\n    this.resize();\n    this.inputEl.addEventListener('keyup', () => this.resize());\n    this.inputEl.addEventListener('keydown', e => this.onKeydown(e));\n  }\n\n  /**\n   * Replace the pre element with a textarea. The examples are initially rendered\n   * as pre elements so they're fully visible when JS is disabled.\n   */\n  makeTextArea(el: Element | null): HTMLTextAreaElement {\n    const t = document.createElement('textarea');\n    t.classList.add('Documentation-exampleCode', 'code');\n    t.spellcheck = false;\n    t.value = el?.textContent ?? '';\n    el?.parentElement?.replaceChild(t, el);\n    return t;\n  }\n\n  /**\n   * Retrieve the hash value of the anchor element.\n   */\n  getAnchorHash(): string | undefined {\n    return this.anchorEl?.hash;\n  }\n\n  /**\n   * Expands the current playground example.\n   */\n  expand(): void {\n    this.exampleEl.open = true;\n  }\n\n  /**\n   * Resizes the input element to accomodate the amount of text present.\n   */\n  private resize(): void {\n    if (this.inputEl?.value) {\n      const numLineBreaks = (this.inputEl.value.match(/\\n/g) || []).length;\n      // min-height + lines x line-height + padding + border\n      this.inputEl.style.height = `${(20 + numLineBreaks * 20 + 12 + 2) / 16}rem`;\n    }\n  }\n\n  /**\n   * Handler to override keyboard behavior in the playground's\n   * textarea element.\n   *\n   * Tab key inserts tabs into the example playground instead of\n   * switching to the next interactive element.\n   * @param e input element keyboard event.\n   */\n  private onKeydown(e: KeyboardEvent) {\n    if (e.key === 'Tab') {\n      document.execCommand('insertText', false, '\\t');\n      e.preventDefault();\n    }\n  }\n\n  /**\n   * Changes the text of the example's input box.\n   */\n  private setInputText(output: string) {\n    if (this.inputEl) {\n      this.inputEl.value = output;\n    }\n  }\n\n  /**\n   * Changes the text of the example's output box.\n   */\n  private setOutputText(output: string) {\n    if (this.outputEl) {\n      this.outputEl.textContent = output;\n    }\n  }\n\n  /**\n   * Sets the error message text and overwrites\n   * output box to indicate a failed response.\n   */\n  private setErrorText(err: string) {\n    if (this.errorEl) {\n      this.errorEl.textContent = err;\n    }\n    this.setOutputText('An error has occurred\u2026');\n  }\n\n  /**\n   * Opens a new window to play.golang.org using the\n   * example snippet's code in the playground.\n   */\n  private handleShareButtonClick() {\n    const PLAYGROUND_BASE_URL = 'https://play.golang.org/p/';\n\n    this.setOutputText('Waiting for remote server\u2026');\n\n    fetch('/play/share', {\n      method: 'POST',\n      body: this.inputEl?.value,\n    })\n      .then(res => res.text())\n      .then(shareId => {\n        const href = PLAYGROUND_BASE_URL + shareId;\n        this.setOutputText(`<a href=\"${href}\">${href}</a>`);\n        window.open(href);\n      })\n      .catch(err => {\n        this.setErrorText(err);\n      });\n  }\n\n  /**\n   * Runs gofmt on the example snippet in the playground.\n   */\n  private handleFormatButtonClick() {\n    this.setOutputText('Waiting for remote server\u2026');\n    const body = new FormData();\n    body.append('body', this.inputEl?.value ?? '');\n\n    fetch('/play/fmt', {\n      method: 'POST',\n      body: body,\n    })\n      .then(res => res.json())\n      .then(({ Body, Error }) => {\n        this.setOutputText(Error || 'Done.');\n        if (Body) {\n          this.setInputText(Body);\n          this.resize();\n        }\n      })\n      .catch(err => {\n        this.setErrorText(err);\n      });\n  }\n\n  /**\n   * Runs the code snippet in the example playground.\n   */\n  private handleRunButtonClick() {\n    this.setOutputText('Waiting for remote server\u2026');\n\n    fetch('/play/compile', {\n      method: 'POST',\n      body: JSON.stringify({ body: this.inputEl?.value, version: 2 }),\n    })\n      .then(res => res.json())\n      .then(async ({ Events, Errors }) => {\n        this.setOutputText(Errors || '');\n        for (const e of Events || []) {\n          this.setOutputText(e.Message);\n          await new Promise(resolve => setTimeout(resolve, e.Delay / 1000000));\n        }\n      })\n      .catch(err => {\n        this.setErrorText(err);\n      });\n  }\n}\n\nexport function initPlaygrounds(): void {\n  const exampleHashRegex = location.hash.match(/^#(example-.*)$/);\n  if (exampleHashRegex) {\n    const exampleHashEl = document.getElementById(exampleHashRegex[1]) as HTMLDetailsElement;\n    if (exampleHashEl) {\n      exampleHashEl.open = true;\n    }\n  }\n\n  // We use a spread operator to convert a nodelist into an array of elements.\n  const exampleHrefs = [\n    ...document.querySelectorAll<HTMLAnchorElement>(PlayExampleClassName.PLAY_HREF),\n  ];\n\n  /**\n   * Sometimes exampleHrefs and playContainers are in different order, so we\n   * find an exampleHref from a common hash.\n   * @param playContainer - playground container\n   */\n  const findExampleHash = (playContainer: PlaygroundExampleController) =>\n    exampleHrefs.find(ex => {\n      return ex.hash === playContainer.getAnchorHash();\n    });\n\n  for (const el of document.querySelectorAll(PlayExampleClassName.PLAY_CONTAINER)) {\n    // There should be the same amount of hrefs referencing examples as example containers.\n    const playContainer = new PlaygroundExampleController(el as HTMLDetailsElement);\n    const exampleHref = findExampleHash(playContainer);\n    if (exampleHref) {\n      exampleHref.addEventListener('click', () => {\n        playContainer.expand();\n      });\n    } else {\n      console.warn('example href not found');\n    }\n  }\n}\n", "interface TagManagerEvent {\n  /**\n   * event is the name of the event, used to filter events in\n   * Google Analytics.\n   */\n  event: string;\n\n  /**\n   * event_category is a name that you supply as a way to group objects\n   * that to analyze. Typically, you will use the same category name\n   * multiple times over related UI elements (buttons, links, etc).\n   */\n  event_category?: string;\n\n  /**\n   * event_action is used to name the type of event or interaction you\n   * want to measure for a particular web object. For example, with a\n   * single \"form\" category, you can analyze a number of specific events\n   * with this parameter, such as: form entered, form submitted.\n   */\n  event_action?: string;\n\n  /**\n   * event_label provide additional information for events that you want\n   * to analyze, such as the text label of a link.\n   */\n  event_label?: string;\n\n  /**\n   * gtm.start is used to initialize Google Tag Manager.\n   */\n  'gtm.start'?: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ndeclare global {\n  interface Window {\n    dataLayer?: (TagManagerEvent | VoidFunction)[];\n    ga?: unknown;\n  }\n}\n\n/**\n * track sends events to Google Tag Manager.\n */\nexport function track(\n  event: string | TagManagerEvent,\n  category?: string,\n  action?: string,\n  label?: string\n): void {\n  window.dataLayer ??= [];\n  if (typeof event === 'string') {\n    window.dataLayer.push({\n      event,\n      event_category: category,\n      event_action: action,\n      event_label: label,\n    });\n  } else {\n    window.dataLayer.push(event);\n  }\n}\n\n/**\n * func adds functions to run sequentionally after\n * Google Tag Manager is ready.\n */\nexport function func(fn: () => void): void {\n  window.dataLayer ??= [];\n  window.dataLayer.push(fn);\n}\n", "/*!\n * @license\n * Copyright 2019-2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { track } from '../analytics/analytics';\n\n/**\n * Options are keyhandler callback options.\n */\ninterface Options {\n  /**\n   * target is the element the key event should filter on. The\n   * default target is the document.\n   */\n  target?: Element;\n\n  /**\n   * withMeta specifies if the event callback should fire when\n   * the key is pressed with a meta key (ctrl, alt, etc). By\n   * default meta keypresses are ignored.\n   */\n  withMeta?: boolean;\n}\n\n/**\n * KeyHandler is the config for a keyboard event callback.\n */\ninterface KeyHandler extends Options {\n  description: string;\n  callback: (e: KeyboardEvent) => void;\n}\n\n/**\n * KeyboardController controls event callbacks for sitewide\n * keyboard events. Multiple callbacks can be registered for\n * a single key and by default the controller ignores events\n * for text input targets.\n */\nclass KeyboardController {\n  handlers: Record<string, Set<KeyHandler>>;\n\n  constructor() {\n    this.handlers = {};\n    document.addEventListener('keydown', e => this.handleKeyPress(e));\n  }\n\n  /**\n   * on registers keyboard event callbacks.\n   * @param key the key to register.\n   * @param description name of the event.\n   * @param callback event callback.\n   * @param options set target and withMeta options to override the default behaviors.\n   */\n  on(key: string, description: string, callback: (e: KeyboardEvent) => void, options?: Options) {\n    this.handlers[key] ??= new Set();\n    this.handlers[key].add({ description, callback, ...options });\n    return this;\n  }\n\n  private handleKeyPress(e: KeyboardEvent) {\n    for (const handler of this.handlers[e.key.toLowerCase()] ?? new Set()) {\n      if (handler.target && handler.target !== e.target) {\n        return;\n      }\n      const t = e.target as HTMLElement | null;\n      if (\n        !handler.target &&\n        (t?.tagName === 'INPUT' || t?.tagName === 'SELECT' || t?.tagName === 'TEXTAREA')\n      ) {\n        return;\n      }\n      if (t?.isContentEditable) {\n        return;\n      }\n      if (\n        (handler.withMeta && !(e.ctrlKey || e.metaKey)) ||\n        (!handler.withMeta && (e.ctrlKey || e.metaKey))\n      ) {\n        return;\n      }\n      track('keypress', 'hotkeys', `${e.key} pressed`, handler.description);\n      handler.callback(e);\n    }\n  }\n}\n\nexport const keyboard = new KeyboardController();\n", "/*!\n * @license\n * Copyright 2019-2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n// This file implements the behavior of the \"jump to symbol\" dialog for Go\n// package documentation, as well as the simple dialog that displays keyboard\n// shortcuts.\n\n// The DOM for the dialogs is at the bottom of static/frontend/unit/main/_modals.tmpl.\n// The CSS is in static/frontend/unit/main/_modals.css.\n\n// The dialog is activated by pressing the 'f' key. It presents a list\n// (#JumpDialog-list) of all Go symbols displayed in the documentation.\n// Entering text in the dialog's text box (#JumpDialog-filter) restricts the\n// list to symbols containing the text. Clicking on an symbol jumps to\n// its documentation.\n\n// This code is based on\n// https://go.googlesource.com/gddo/+/refs/heads/master/gddo-server/assets/site.js.\n// It was modified to remove the dependence on jquery and bootstrap.\n\nimport { keyboard } from '../keyboard/keyboard';\n\nconst jumpDialog = document.querySelector<HTMLDialogElement>('.JumpDialog');\nconst jumpBody = jumpDialog?.querySelector<HTMLDivElement>('.JumpDialog-body');\nconst jumpList = jumpDialog?.querySelector<HTMLDivElement>('.JumpDialog-list');\nconst jumpFilter = jumpDialog?.querySelector<HTMLInputElement>('.JumpDialog-input');\nconst doc = document.querySelector<HTMLDivElement>('.js-documentation');\n\ninterface JumpListItem {\n  link: HTMLAnchorElement;\n  name: string;\n  kind: string;\n  lower: string;\n}\n\nlet jumpListItems: JumpListItem[] | undefined; // All the symbols in the doc; computed only once.\n\n// collectJumpListItems returns a list of items, one for each symbol in the\n// documentation on the current page.\n//\n// It uses the data-kind attribute generated in the documentation HTML to find\n// the symbols and their id attributes.\n//\n// If there are no data-kind attributes, then we have older doc; fall back to\n// a less precise method.\nfunction collectJumpListItems() {\n  const items = [];\n  if (!doc) return;\n  for (const el of doc.querySelectorAll('[data-kind]')) {\n    items.push(newJumpListItem(el));\n  }\n\n  // Clicking on any of the links closes the dialog.\n  for (const item of items) {\n    item.link.addEventListener('click', function () {\n      jumpDialog?.close();\n    });\n  }\n  // Sort case-insensitively by symbol name.\n  items.sort(function (a, b) {\n    return a.lower.localeCompare(b.lower);\n  });\n  return items;\n}\n\n// newJumpListItem creates a new item for the DOM element el.\n// An item is an object with:\n// - name: the element's id (which is the symbol name)\n// - kind: the element's kind (function, variable, etc.),\n// - link: a link ('a' tag) to the element\n// - lower: the name in lower case, just for sorting\nfunction newJumpListItem(el: Element): JumpListItem {\n  const a = document.createElement('a');\n  const name = el.getAttribute('id');\n  a.setAttribute('href', '#' + name);\n  a.setAttribute('tabindex', '-1');\n  a.setAttribute('data-gtmc', 'jump to link');\n  const kind = el.getAttribute('data-kind');\n  return {\n    link: a,\n    name: name ?? '',\n    kind: kind ?? '',\n    lower: name?.toLowerCase() ?? '', // for sorting\n  };\n}\n\nlet lastFilterValue: string; // The last contents of the filter text box.\nlet activeJumpItem = -1; // The index of the currently active item in the list.\n\n// updateJumpList sets the elements of the dialog list to\n// everything whose name contains filter.\nfunction updateJumpList(filter: string) {\n  lastFilterValue = filter;\n  if (!jumpListItems) {\n    jumpListItems = collectJumpListItems();\n  }\n  setActiveJumpItem(-1);\n\n  // Remove all children from list.\n  while (jumpList?.firstChild) {\n    jumpList.firstChild.remove();\n  }\n\n  if (filter) {\n    // A filter is set. We treat the filter as a substring that can appear in\n    // an item name (case insensitive), and find the following matches - in\n    // order of priority:\n    //\n    // 1. Exact matches (the filter matches the item's name exactly)\n    // 2. Prefix matches (the item's name starts with filter)\n    // 3. Infix matches (the filter is a substring of the item's name)\n    const filterLowerCase = filter.toLowerCase();\n\n    const exactMatches = [];\n    const prefixMatches = [];\n    const infixMatches = [];\n\n    // makeLinkHtml creates the link name HTML for a list item. item is the DOM\n    // item. item.name.substr(boldStart, boldEnd) will be bolded.\n    const makeLinkHtml = (item: JumpListItem, boldStart: number, boldEnd: number) => {\n      return (\n        item.name.substring(0, boldStart) +\n        '<b>' +\n        item.name.substring(boldStart, boldEnd) +\n        '</b>' +\n        item.name.substring(boldEnd)\n      );\n    };\n\n    for (const item of jumpListItems ?? []) {\n      const nameLowerCase = item.name.toLowerCase();\n\n      if (nameLowerCase === filterLowerCase) {\n        item.link.innerHTML = makeLinkHtml(item, 0, item.name.length);\n        exactMatches.push(item);\n      } else if (nameLowerCase.startsWith(filterLowerCase)) {\n        item.link.innerHTML = makeLinkHtml(item, 0, filter.length);\n        prefixMatches.push(item);\n      } else {\n        const index = nameLowerCase.indexOf(filterLowerCase);\n        if (index > -1) {\n          item.link.innerHTML = makeLinkHtml(item, index, index + filter.length);\n          infixMatches.push(item);\n        }\n      }\n    }\n\n    for (const item of exactMatches.concat(prefixMatches).concat(infixMatches)) {\n      jumpList?.appendChild(item.link);\n    }\n  } else {\n    if (!jumpListItems || jumpListItems.length === 0) {\n      const msg = document.createElement('i');\n      msg.innerHTML = 'There are no symbols on this page.';\n      jumpList?.appendChild(msg);\n    }\n    // No filter set; display all items in their existing order.\n    for (const item of jumpListItems ?? []) {\n      item.link.innerHTML = item.name + ' <i>' + item.kind + '</i>';\n      jumpList?.appendChild(item.link);\n    }\n  }\n\n  if (jumpBody) {\n    jumpBody.scrollTop = 0;\n  }\n  if (jumpListItems?.length && jumpList && jumpList.children.length > 0) {\n    setActiveJumpItem(0);\n  }\n}\n\n// Set the active jump item to n.\nfunction setActiveJumpItem(n: number) {\n  const cs = jumpList?.children as HTMLCollectionOf<HTMLElement> | null | undefined;\n  if (!cs || !jumpBody) {\n    return;\n  }\n  if (activeJumpItem >= 0) {\n    cs[activeJumpItem].classList.remove('JumpDialog-active');\n  }\n  if (n >= cs.length) {\n    n = cs.length - 1;\n  }\n  if (n >= 0) {\n    cs[n].classList.add('JumpDialog-active');\n\n    // Scroll so the active item is visible.\n    // For some reason cs[n].scrollIntoView() doesn't behave as I'd expect:\n    // it moves the entire dialog box in the viewport.\n\n    // Get the top and bottom of the active item relative to jumpBody.\n    const activeTop = cs[n].offsetTop - cs[0].offsetTop;\n    const activeBottom = activeTop + cs[n].clientHeight;\n    if (activeTop < jumpBody.scrollTop) {\n      // Off the top; scroll up.\n      jumpBody.scrollTop = activeTop;\n    } else if (activeBottom > jumpBody.scrollTop + jumpBody.clientHeight) {\n      // Off the bottom; scroll down.\n      jumpBody.scrollTop = activeBottom - jumpBody.clientHeight;\n    }\n  }\n  activeJumpItem = n;\n}\n\n// Increment the activeJumpItem by delta.\nfunction incActiveJumpItem(delta: number) {\n  if (activeJumpItem < 0) {\n    return;\n  }\n  let n = activeJumpItem + delta;\n  if (n < 0) {\n    n = 0;\n  }\n  setActiveJumpItem(n);\n}\n\nexport function initModals(): void {\n  // Pressing a key in the filter updates the list (if the filter actually changed).\n  jumpFilter?.addEventListener('keyup', function () {\n    if (jumpFilter.value.toUpperCase() != lastFilterValue.toUpperCase()) {\n      updateJumpList(jumpFilter.value);\n    }\n  });\n\n  // Pressing enter in the filter selects the first element in the list.\n  jumpFilter?.addEventListener('keydown', function (event) {\n    const upArrow = 38;\n    const downArrow = 40;\n    const enterKey = 13;\n    switch (event.which) {\n      case upArrow:\n        incActiveJumpItem(-1);\n        event.preventDefault();\n        break;\n      case downArrow:\n        incActiveJumpItem(1);\n        event.preventDefault();\n        break;\n      case enterKey:\n        if (activeJumpItem >= 0) {\n          if (jumpList) {\n            (jumpList.children[activeJumpItem] as HTMLElement).click();\n            event.preventDefault();\n          }\n        }\n        break;\n    }\n  });\n\n  const shortcutsDialog = document.querySelector<HTMLDialogElement>('.ShortcutsDialog');\n\n  // - Pressing 'f' or 'F' opens the jump-to-symbol dialog.\n  // - Pressing '?' opens up the shortcut dialog.\n  // Ignore a keypress if a dialog is already open, or if it is pressed on a\n  // component that wants to consume it.\n  keyboard\n    .on('f', 'open jump to modal', e => {\n      if (jumpDialog?.open || shortcutsDialog?.open) {\n        return;\n      }\n      e.preventDefault();\n      if (jumpFilter) {\n        jumpFilter.value = '';\n      }\n      jumpDialog?.showModal();\n      jumpFilter?.focus();\n      updateJumpList('');\n    })\n    .on('?', 'open shortcuts modal', () => {\n      if (jumpDialog?.open || shortcutsDialog?.open) {\n        return;\n      }\n      shortcutsDialog?.showModal();\n    });\n\n  const jumpOutlineInput = document.querySelector('.js-jumpToInput');\n  if (jumpOutlineInput) {\n    jumpOutlineInput.addEventListener('click', () => {\n      if (jumpFilter) {\n        jumpFilter.value = '';\n      }\n      updateJumpList('');\n    });\n  }\n\n  document.querySelector('.js-openShortcuts')?.addEventListener('click', () => {\n    shortcutsDialog?.showModal();\n  });\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { TreeNavController } from './tree.js';\n\nexport class SelectNavController {\n  constructor(private el: Element) {\n    this.el.addEventListener('change', e => {\n      const target = e.target as HTMLSelectElement;\n      let href = target.value;\n      if (!target.value.startsWith('/')) {\n        href = '/' + href;\n      }\n      window.location.href = href;\n    });\n  }\n}\n\nexport function makeSelectNav(tree: TreeNavController): HTMLLabelElement {\n  const label = document.createElement('label');\n  label.classList.add('go-Label');\n  label.setAttribute('aria-label', 'Menu');\n  const select = document.createElement('select');\n  select.classList.add('go-Select', 'js-selectNav');\n  label.appendChild(select);\n  const outline = document.createElement('optgroup');\n  outline.label = 'Outline';\n  select.appendChild(outline);\n  const groupMap: Record<string, HTMLOptGroupElement> = {};\n  let group: HTMLOptGroupElement;\n  for (const t of tree.treeitems) {\n    if (Number(t.depth) > 4) continue;\n    if (t.groupTreeitem) {\n      group = groupMap[t.groupTreeitem.label];\n      if (!group) {\n        group = groupMap[t.groupTreeitem.label] = document.createElement('optgroup');\n        group.label = t.groupTreeitem.label;\n        select.appendChild(group);\n      }\n    } else {\n      group = outline;\n    }\n    const o = document.createElement('option');\n    o.label = t.label;\n    o.textContent = t.label;\n    o.value = (t.el as HTMLAnchorElement).href.replace(window.location.origin, '').replace('/', '');\n    group.appendChild(o);\n  }\n  tree.addObserver(t => {\n    const hash = (t.el as HTMLAnchorElement).hash;\n    const value = select.querySelector<HTMLOptionElement>(`[value$=\"${hash}\"]`)?.value;\n    if (value) {\n      select.value = value;\n    }\n  }, 50);\n  return label;\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * TreeNavController is the navigation tree component of the documentation page.\n * It adds accessiblity attributes to a tree, observes the heading elements\n * focus the topmost link for headings visible on the page, and implements the\n * WAI-ARIA Treeview Design Pattern with full\n * [keyboard support](https://www.w3.org/TR/wai-aria-practices/examples/treeview/treeview-2/treeview-2a.html#kbd_label).\n */\nexport class TreeNavController {\n  treeitems: TreeItem[];\n\n  /**\n   * firstChars is the first character of each treeitem in the same order\n   * as this.treeitems. We use this array to set focus by character when\n   * navigating the tree with a keyboard.\n   */\n  private firstChars: string[];\n  private firstTreeitem: TreeItem | null;\n  private lastTreeitem: TreeItem | null;\n  private observerCallbacks: ((t: TreeItem) => void)[];\n\n  constructor(private el: HTMLElement) {\n    this.treeitems = [];\n    this.firstChars = [];\n    this.firstTreeitem = null;\n    this.lastTreeitem = null;\n    this.observerCallbacks = [];\n    this.init();\n  }\n\n  private init(): void {\n    this.handleResize();\n    window.addEventListener('resize', this.handleResize);\n    this.findTreeItems();\n    this.updateVisibleTreeitems();\n    this.observeTargets();\n    if (this.firstTreeitem) {\n      this.firstTreeitem.el.tabIndex = 0;\n    }\n  }\n\n  private handleResize = (): void => {\n    this.el.style.setProperty('--js-tree-height', '100vh');\n    this.el.style.setProperty('--js-tree-height', this.el.clientHeight + 'px');\n  };\n\n  private observeTargets() {\n    this.addObserver(treeitem => {\n      this.expandTreeitem(treeitem);\n      this.setSelected(treeitem);\n      // TODO: Fix scroll issue in https://golang.org/issue/47450.\n      // treeitem.el.scrollIntoView({ block: 'nearest' });\n    });\n\n    const targets = new Map<string, boolean>();\n    const observer = new IntersectionObserver(\n      entries => {\n        for (const entry of entries) {\n          targets.set(entry.target.id, entry.isIntersecting || entry.intersectionRatio === 1);\n        }\n        for (const [id, isIntersecting] of targets) {\n          if (isIntersecting) {\n            const active = this.treeitems.find(t =>\n              (t.el as HTMLAnchorElement)?.href.endsWith(`#${id}`)\n            );\n            if (active) {\n              for (const fn of this.observerCallbacks) {\n                fn(active);\n              }\n            }\n            break;\n          }\n        }\n      },\n      {\n        threshold: 1.0,\n        rootMargin: '-60px 0px 0px 0px',\n      }\n    );\n\n    for (const href of this.treeitems.map(t => t.el.getAttribute('href'))) {\n      if (href) {\n        const id = href.replace(window.location.origin, '').replace('/', '').replace('#', '');\n        const target = document.getElementById(id);\n        if (target) {\n          observer.observe(target);\n        }\n      }\n    }\n  }\n\n  addObserver(fn: (t: TreeItem) => void, delay = 200): void {\n    this.observerCallbacks.push(debounce(fn, delay));\n  }\n\n  setFocusToNextItem(currentItem: TreeItem): void {\n    let nextItem = null;\n    for (let i = currentItem.index + 1; i < this.treeitems.length; i++) {\n      const ti = this.treeitems[i];\n      if (ti.isVisible) {\n        nextItem = ti;\n        break;\n      }\n    }\n    if (nextItem) {\n      this.setFocusToItem(nextItem);\n    }\n  }\n\n  setFocusToPreviousItem(currentItem: TreeItem): void {\n    let prevItem = null;\n    for (let i = currentItem.index - 1; i > -1; i--) {\n      const ti = this.treeitems[i];\n      if (ti.isVisible) {\n        prevItem = ti;\n        break;\n      }\n    }\n    if (prevItem) {\n      this.setFocusToItem(prevItem);\n    }\n  }\n\n  setFocusToParentItem(currentItem: TreeItem): void {\n    if (currentItem.groupTreeitem) {\n      this.setFocusToItem(currentItem.groupTreeitem);\n    }\n  }\n\n  setFocusToFirstItem(): void {\n    this.firstTreeitem && this.setFocusToItem(this.firstTreeitem);\n  }\n\n  setFocusToLastItem(): void {\n    this.lastTreeitem && this.setFocusToItem(this.lastTreeitem);\n  }\n\n  setSelected(currentItem: TreeItem): void {\n    for (const l1 of this.el.querySelectorAll('[aria-expanded=\"true\"]')) {\n      if (l1 === currentItem.el) continue;\n      if (!l1.nextElementSibling?.contains(currentItem.el)) {\n        l1.setAttribute('aria-expanded', 'false');\n      }\n    }\n    for (const l1 of this.el.querySelectorAll('[aria-selected]')) {\n      if (l1 !== currentItem.el) {\n        l1.setAttribute('aria-selected', 'false');\n      }\n    }\n    currentItem.el.setAttribute('aria-selected', 'true');\n    this.updateVisibleTreeitems();\n    this.setFocusToItem(currentItem, false);\n  }\n\n  expandTreeitem(treeitem: TreeItem): void {\n    let currentItem: TreeItem | null = treeitem;\n    while (currentItem) {\n      if (currentItem.isExpandable) {\n        currentItem.el.setAttribute('aria-expanded', 'true');\n      }\n      currentItem = currentItem.groupTreeitem;\n    }\n    this.updateVisibleTreeitems();\n  }\n\n  expandAllSiblingItems(currentItem: TreeItem): void {\n    for (const ti of this.treeitems) {\n      if (ti.groupTreeitem === currentItem.groupTreeitem && ti.isExpandable) {\n        this.expandTreeitem(ti);\n      }\n    }\n  }\n\n  collapseTreeitem(currentItem: TreeItem): void {\n    let groupTreeitem = null;\n\n    if (currentItem.isExpanded()) {\n      groupTreeitem = currentItem;\n    } else {\n      groupTreeitem = currentItem.groupTreeitem;\n    }\n\n    if (groupTreeitem) {\n      groupTreeitem.el.setAttribute('aria-expanded', 'false');\n      this.updateVisibleTreeitems();\n      this.setFocusToItem(groupTreeitem);\n    }\n  }\n\n  setFocusByFirstCharacter(currentItem: TreeItem, char: string): void {\n    let start: number, index: number;\n    char = char.toLowerCase();\n\n    // Get start index for search based on position of currentItem\n    start = currentItem.index + 1;\n    if (start === this.treeitems.length) {\n      start = 0;\n    }\n\n    // Check remaining slots in the menu\n    index = this.getIndexFirstChars(start, char);\n\n    // If not found in remaining slots, check from beginning\n    if (index === -1) {\n      index = this.getIndexFirstChars(0, char);\n    }\n\n    // If match was found...\n    if (index > -1) {\n      this.setFocusToItem(this.treeitems[index]);\n    }\n  }\n\n  private findTreeItems() {\n    const findItems = (el: HTMLElement, group: TreeItem | null) => {\n      let ti = group;\n      let curr = el.firstElementChild as HTMLElement;\n      while (curr) {\n        if (curr.tagName === 'A' || curr.tagName === 'SPAN') {\n          ti = new TreeItem(curr, this, group);\n          this.treeitems.push(ti);\n          this.firstChars.push(ti.label.substring(0, 1).toLowerCase());\n        }\n        if (curr.firstElementChild) {\n          findItems(curr, ti);\n        }\n        curr = curr.nextElementSibling as HTMLElement;\n      }\n    };\n    findItems(this.el as HTMLElement, null);\n    this.treeitems.map((ti, idx) => (ti.index = idx));\n  }\n\n  private updateVisibleTreeitems(): void {\n    this.firstTreeitem = this.treeitems[0];\n\n    for (const ti of this.treeitems) {\n      let parent = ti.groupTreeitem;\n      ti.isVisible = true;\n      while (parent && parent.el !== this.el) {\n        if (!parent.isExpanded()) {\n          ti.isVisible = false;\n        }\n        parent = parent.groupTreeitem;\n      }\n      if (ti.isVisible) {\n        this.lastTreeitem = ti;\n      }\n    }\n  }\n\n  private setFocusToItem(treeitem: TreeItem, focusEl = true) {\n    treeitem.el.tabIndex = 0;\n    if (focusEl) {\n      treeitem.el.focus();\n    }\n    for (const ti of this.treeitems) {\n      if (ti !== treeitem) {\n        ti.el.tabIndex = -1;\n      }\n    }\n  }\n\n  private getIndexFirstChars(startIndex: number, char: string): number {\n    for (let i = startIndex; i < this.firstChars.length; i++) {\n      if (this.treeitems[i].isVisible && char === this.firstChars[i]) {\n        return i;\n      }\n    }\n    return -1;\n  }\n}\n\nclass TreeItem {\n  el: HTMLElement;\n  groupTreeitem: TreeItem | null;\n  label: string;\n  isExpandable: boolean;\n  isVisible: boolean;\n  depth: number;\n  index: number;\n\n  private tree: TreeNavController;\n  private isInGroup: boolean;\n\n  constructor(el: HTMLElement, treeObj: TreeNavController, group: TreeItem | null) {\n    el.tabIndex = -1;\n    this.el = el;\n    this.groupTreeitem = group;\n    this.label = el.textContent?.trim() ?? '';\n    this.tree = treeObj;\n    this.depth = (group?.depth || 0) + 1;\n    this.index = 0;\n\n    const parent = el.parentElement;\n    if (parent?.tagName.toLowerCase() === 'li') {\n      parent?.setAttribute('role', 'none');\n    }\n    el.setAttribute('aria-level', this.depth + '');\n    if (el.getAttribute('aria-label')) {\n      this.label = el?.getAttribute('aria-label')?.trim() ?? '';\n    }\n\n    this.isExpandable = false;\n    this.isVisible = false;\n    this.isInGroup = !!group;\n\n    let curr = el.nextElementSibling;\n    while (curr) {\n      if (curr.tagName.toLowerCase() == 'ul') {\n        const groupId = `${group?.label ?? ''} nav group ${this.label}`.replace(/[\\W_]+/g, '_');\n        el.setAttribute('aria-owns', groupId);\n        el.setAttribute('aria-expanded', 'false');\n        curr.setAttribute('role', 'group');\n        curr.setAttribute('id', groupId);\n        this.isExpandable = true;\n        break;\n      }\n\n      curr = curr.nextElementSibling;\n    }\n    this.init();\n  }\n\n  private init() {\n    this.el.tabIndex = -1;\n    if (!this.el.getAttribute('role')) {\n      this.el.setAttribute('role', 'treeitem');\n    }\n    this.el.addEventListener('keydown', this.handleKeydown.bind(this));\n    this.el.addEventListener('click', this.handleClick.bind(this));\n    this.el.addEventListener('focus', this.handleFocus.bind(this));\n    this.el.addEventListener('blur', this.handleBlur.bind(this));\n  }\n\n  isExpanded() {\n    if (this.isExpandable) {\n      return this.el.getAttribute('aria-expanded') === 'true';\n    }\n\n    return false;\n  }\n\n  isSelected() {\n    return this.el.getAttribute('aria-selected') === 'true';\n  }\n\n  private handleClick(event: MouseEvent) {\n    // only process click events that directly happened on this treeitem\n    if (event.target !== this.el && event.target !== this.el.firstElementChild) {\n      return;\n    }\n    if (this.isExpandable) {\n      if (this.isExpanded() && this.isSelected()) {\n        this.tree.collapseTreeitem(this);\n      } else {\n        this.tree.expandTreeitem(this);\n      }\n      event.stopPropagation();\n    }\n    this.tree.setSelected(this);\n  }\n\n  private handleFocus() {\n    let el = this.el;\n    if (this.isExpandable) {\n      el = (el.firstElementChild as HTMLElement) ?? el;\n    }\n    el.classList.add('focus');\n  }\n\n  private handleBlur() {\n    let el = this.el;\n    if (this.isExpandable) {\n      el = (el.firstElementChild as HTMLElement) ?? el;\n    }\n    el.classList.remove('focus');\n  }\n\n  private handleKeydown(event: KeyboardEvent) {\n    if (event.altKey || event.ctrlKey || event.metaKey) {\n      return;\n    }\n\n    let captured = false;\n    switch (event.key) {\n      case ' ':\n      case 'Enter':\n        if (this.isExpandable) {\n          if (this.isExpanded() && this.isSelected()) {\n            this.tree.collapseTreeitem(this);\n          } else {\n            this.tree.expandTreeitem(this);\n          }\n          captured = true;\n        } else {\n          event.stopPropagation();\n        }\n        this.tree.setSelected(this);\n        break;\n\n      case 'ArrowUp':\n        this.tree.setFocusToPreviousItem(this);\n        captured = true;\n        break;\n\n      case 'ArrowDown':\n        this.tree.setFocusToNextItem(this);\n        captured = true;\n        break;\n\n      case 'ArrowRight':\n        if (this.isExpandable) {\n          if (this.isExpanded()) {\n            this.tree.setFocusToNextItem(this);\n          } else {\n            this.tree.expandTreeitem(this);\n          }\n        }\n        captured = true;\n        break;\n\n      case 'ArrowLeft':\n        if (this.isExpandable && this.isExpanded()) {\n          this.tree.collapseTreeitem(this);\n          captured = true;\n        } else {\n          if (this.isInGroup) {\n            this.tree.setFocusToParentItem(this);\n            captured = true;\n          }\n        }\n        break;\n\n      case 'Home':\n        this.tree.setFocusToFirstItem();\n        captured = true;\n        break;\n\n      case 'End':\n        this.tree.setFocusToLastItem();\n        captured = true;\n        break;\n\n      default:\n        if (event.key.length === 1 && event.key.match(/\\S/)) {\n          if (event.key == '*') {\n            this.tree.expandAllSiblingItems(this);\n          } else {\n            this.tree.setFocusByFirstCharacter(this, event.key);\n          }\n          captured = true;\n        }\n        break;\n    }\n\n    if (captured) {\n      event.stopPropagation();\n      event.preventDefault();\n    }\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction debounce<T extends (...args: any[]) => any>(func: T, wait: number) {\n  let timeout: ReturnType<typeof setTimeout> | null;\n  return (...args: Parameters<T>) => {\n    const later = () => {\n      timeout = null;\n      func(...args);\n    };\n    if (timeout) {\n      clearTimeout(timeout);\n    }\n    timeout = setTimeout(later, wait);\n  };\n}\n", "/*!\n * @license\n * Copyright 2020 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * Controller for a table element with expandable rows. Adds event listeners to\n * a toggle within a table row that controls visiblity of additional related\n * rows in the table.\n *\n * @example\n * ```typescript\n * import {ExpandableRowsTableController} from '/static/js/table';\n *\n * const el = document .querySelector<HTMLTableElement>('.js-myTableElement')\n * new ExpandableRowsTableController(el));\n * ```\n */\nexport class ExpandableRowsTableController {\n  private rows: HTMLTableRowElement[];\n  private toggles: HTMLButtonElement[];\n\n  /**\n   * Create a table controller.\n   * @param table - The table element to which the controller binds.\n   */\n  constructor(private table: HTMLTableElement, private toggleAll?: HTMLButtonElement | null) {\n    this.rows = Array.from(table.querySelectorAll<HTMLTableRowElement>('[data-aria-controls]'));\n    this.toggles = Array.from(this.table.querySelectorAll('[aria-expanded]'));\n    this.setAttributes();\n    this.attachEventListeners();\n    this.update();\n  }\n\n  /**\n   * setAttributes sets data-aria-* and data-id attributes to regular\n   * html attributes as a workaround for limitations from safehtml.\n   */\n  private setAttributes() {\n    for (const a of ['data-aria-controls', 'data-aria-labelledby', 'data-id']) {\n      this.table.querySelectorAll(`[${a}]`).forEach(t => {\n        t.setAttribute(a.replace('data-', ''), t.getAttribute(a) ?? '');\n        t.removeAttribute(a);\n      });\n    }\n  }\n\n  private attachEventListeners() {\n    this.rows.forEach(t => {\n      t.addEventListener('click', e => {\n        this.handleToggleClick(e);\n      });\n    });\n    this.toggleAll?.addEventListener('click', () => {\n      this.expandAllItems();\n    });\n\n    document.addEventListener('keydown', e => {\n      if ((e.ctrlKey || e.metaKey) && e.key === 'f') {\n        this.expandAllItems();\n      }\n    });\n  }\n\n  private handleToggleClick(e: MouseEvent) {\n    let target = e.currentTarget as HTMLTableRowElement | null;\n    if (!target?.hasAttribute('aria-expanded')) {\n      target = this.table.querySelector(\n        `button[aria-controls=\"${target?.getAttribute('aria-controls')}\"]`\n      );\n    }\n    const isExpanded = target?.getAttribute('aria-expanded') === 'true';\n    target?.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');\n    e.stopPropagation();\n    this.update();\n  }\n\n  expandAllItems = (): void => {\n    this.toggles.map(t => t.setAttribute('aria-expanded', 'true'));\n    this.update();\n  };\n\n  private collapseAllItems = () => {\n    this.toggles.map(t => t.setAttribute('aria-expanded', 'false'));\n    this.update();\n  };\n\n  private update = () => {\n    this.updateVisibleItems();\n    setTimeout(() => this.updateGlobalToggle());\n  };\n\n  private updateVisibleItems() {\n    this.rows.map(t => {\n      const isExpanded = t?.getAttribute('aria-expanded') === 'true';\n      const rowIds = t?.getAttribute('aria-controls')?.trimEnd().split(' ');\n      rowIds?.map(id => {\n        const target = document.getElementById(`${id}`);\n        if (isExpanded) {\n          target?.classList.add('visible');\n          target?.classList.remove('hidden');\n        } else {\n          target?.classList.add('hidden');\n          target?.classList.remove('visible');\n        }\n      });\n    });\n  }\n\n  private updateGlobalToggle() {\n    if (!this.toggleAll) return;\n    if (this.rows.some(t => t.hasAttribute('aria-expanded'))) {\n      this.toggleAll.style.display = 'block';\n    }\n    const someCollapsed = this.toggles.some(el => el.getAttribute('aria-expanded') === 'false');\n    if (someCollapsed) {\n      this.toggleAll.innerText = 'Expand all';\n      this.toggleAll.onclick = this.expandAllItems;\n    } else {\n      this.toggleAll.innerText = 'Collapse all';\n      this.toggleAll.onclick = this.collapseAllItems;\n    }\n  }\n}\n", "import { initPlaygrounds } from 'static/shared/playground/playground';\nimport { initModals } from 'static/shared/jump/jump';\nimport { SelectNavController, makeSelectNav } from 'static/shared/outline/select';\nimport { TreeNavController } from 'static/shared/outline/tree';\nimport { ExpandableRowsTableController } from 'static/shared/table/table';\n\ninitModals();\ninitPlaygrounds();\n\nconst directories = document.querySelector<HTMLTableElement>('.js-expandableTable');\nif (directories) {\n  const table = new ExpandableRowsTableController(\n    directories,\n    document.querySelector<HTMLButtonElement>('.js-expandAllDirectories')\n  );\n  // Expand directories on page load with expand-directories query param.\n  if (window.location.search.includes('expand-directories')) {\n    table.expandAllItems();\n  }\n}\n\nconst treeEl = document.querySelector<HTMLElement>('.js-tree');\nif (treeEl) {\n  const treeCtrl = new TreeNavController(treeEl);\n  const select = makeSelectNav(treeCtrl);\n  const mobileNav = document.querySelector('.js-mainNavMobile');\n  if (mobileNav && mobileNav.firstElementChild) {\n    mobileNav?.replaceChild(select, mobileNav.firstElementChild);\n  }\n  if (select.firstElementChild) {\n    new SelectNavController(select.firstElementChild);\n  }\n}\n\n/**\n * Event handlers for expanding and collapsing the readme section.\n */\nconst readme = document.querySelector('.js-readme');\nconst readmeContent = document.querySelector('.js-readmeContent');\nconst readmeOutline = document.querySelector('.js-readmeOutline');\nconst readmeExpand = document.querySelectorAll('.js-readmeExpand');\nconst readmeCollapse = document.querySelector('.js-readmeCollapse');\nconst mobileNavSelect = document.querySelector<HTMLSelectElement>('.DocNavMobile-select');\nif (readme && readmeContent && readmeOutline && readmeExpand.length && readmeCollapse) {\n  if (window.location.hash.includes('readme')) {\n    expandReadme();\n  }\n  mobileNavSelect?.addEventListener('change', e => {\n    if ((e.target as HTMLSelectElement).value.startsWith('readme-')) {\n      expandReadme();\n    }\n  });\n  readmeExpand.forEach(el =>\n    el.addEventListener('click', e => {\n      e.preventDefault();\n      expandReadme();\n      readme.scrollIntoView();\n    })\n  );\n  readmeCollapse.addEventListener('click', e => {\n    e.preventDefault();\n    readme.classList.remove('UnitReadme--expanded');\n    if (readmeExpand[1]) {\n      readmeExpand[1].scrollIntoView({ block: 'center' });\n    }\n  });\n  readmeContent.addEventListener('keyup', () => {\n    expandReadme();\n  });\n  readmeContent.addEventListener('click', () => {\n    expandReadme();\n  });\n  readmeOutline.addEventListener('click', () => {\n    expandReadme();\n  });\n  document.addEventListener('keydown', e => {\n    if ((e.ctrlKey || e.metaKey) && e.key === 'f') {\n      expandReadme();\n    }\n  });\n}\n\n/**\n * expandReadme expands the readme and adds the section-readme hash to the\n * URL so it stays expanded when navigating back from an external link.\n */\nfunction expandReadme() {\n  history.replaceState(null, '', `${location.pathname}#section-readme`);\n  readme?.classList.add('UnitReadme--expanded');\n}\n\n/**\n * Expand details items that are focused. This will expand\n * deprecated symbols when they are navigated to from the index\n * or a direct link.\n */\nfunction openDeprecatedSymbol() {\n  if (!location.hash) return;\n  const heading = document.getElementById(location.hash.slice(1));\n  const grandParent = heading?.parentElement?.parentElement as HTMLDetailsElement | null;\n  if (grandParent?.nodeName === 'DETAILS') {\n    grandParent.open = true;\n  }\n}\nopenDeprecatedSymbol();\nwindow.addEventListener('hashchange', () => openDeprecatedSymbol());\n\n/**\n * Listen for changes in the build context dropdown.\n */\ndocument.querySelectorAll('.js-buildContextSelect').forEach(el => {\n  el.addEventListener('change', e => {\n    window.location.search = `?GOOS=${(e.target as HTMLSelectElement).value}`;\n  });\n});\n"],
+  "mappings": "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",
   "names": []
 }
diff --git a/static/shared/footer/footer.css b/static/shared/footer/footer.css
index bf0d004..774338c 100644
--- a/static/shared/footer/footer.css
+++ b/static/shared/footer/footer.css
@@ -67,6 +67,28 @@
 .go-Footer-listItem a:visited {
   color: var(--color-text-inverted);
 }
+.go-Footer-listItem .go-Button--text {
+  background-color: transparent;
+  font-size: 1rem;
+}
+.go-Footer-listItem [data-value] {
+  display: none;
+}
+
+[data-theme='auto'] .go-Footer-listItem [data-value='auto'],
+:root:not([data-theme]) .go-Footer-listItem [data-value='auto'] {
+  display: initial;
+}
+[data-theme='dark'] .go-Footer-listItem [data-value='dark'] {
+  display: initial;
+}
+[data-theme='light'] .go-Footer-listItem [data-value='light'] {
+  display: initial;
+}
+.go-Footer-toggleTheme,
+.go-Footer-keyboard {
+  margin: 0 0 0.5rem 0;
+}
 
 .go-Footer-googleLogo {
   align-self: flex-end;
@@ -86,4 +108,10 @@
   .go-Footer-listItem + .go-Footer-listItem {
     border-left: var(--border);
   }
+  .go-Footer-toggleTheme {
+    margin: 0 0 0 -0.5rem;
+  }
+  .go-Footer-keyboard {
+    margin: 0;
+  }
 }
diff --git a/static/shared/footer/footer.tmpl b/static/shared/footer/footer.tmpl
index eb23c8e..9608953 100644
--- a/static/shared/footer/footer.tmpl
+++ b/static/shared/footer/footer.tmpl
@@ -116,6 +116,16 @@
             golang.org
           </a>
         </li>
+        <li class="go-Footer-listItem">
+          <button class="go-Button go-Button--text go-Footer-toggleTheme js-toggleTheme" aria-label="Toggle theme">
+            <img data-value="auto" class="go-Icon go-Icon--inverted" height="24" width="24" src="/static/shared/icon/brightness_6_gm_grey_24dp.svg" alt="System theme">
+            <img data-value="dark" class="go-Icon go-Icon--inverted" height="24" width="24" src="/static/shared/icon/brightness_2_gm_grey_24dp.svg" alt="Dark theme">
+            <img data-value="light" class="go-Icon go-Icon--inverted" height="24" width="24" src="/static/shared/icon/light_mode_gm_grey_24dp.svg" alt="Light theme">
+          </button>
+          <button class="go-Button go-Button--text go-Footer-keyboard js-openShortcuts" aria-label="Open shorcuts modal">
+            <img class="go-Icon go-Icon--inverted" height="24" width="24" src="/static/shared/icon/keyboard_grey_24dp.svg" alt="">
+          </button>
+        </li>
       </ul>
       <a class="go-Footer-googleLogo" href="https://google.com" target="_blank"rel="noopener"
           data-gtmc="footer link">
diff --git a/static/shared/icon/icon.md b/static/shared/icon/icon.md
index d5e6860..8e53dd8 100644
--- a/static/shared/icon/icon.md
+++ b/static/shared/icon/icon.md
@@ -87,6 +87,10 @@
 </span>
 
 <span style="display:contents;">
+  <go-icon name="keyboard"></go-icon>
+</span>
+
+<span style="display:contents;">
   <go-icon name="launch"></go-icon>
 </span>
 
diff --git a/static/shared/icon/keyboard_grey_24dp.svg b/static/shared/icon/keyboard_grey_24dp.svg
new file mode 100644
index 0000000..faea75d
--- /dev/null
+++ b/static/shared/icon/keyboard_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"/><path d="M0 0h24v24H0zm0 0h24v24H0z" fill="none"/></svg>
\ No newline at end of file
diff --git a/static/shared/jump/jump.ts b/static/shared/jump/jump.ts
index 917dc2a..22d5c12 100644
--- a/static/shared/jump/jump.ts
+++ b/static/shared/jump/jump.ts
@@ -286,4 +286,8 @@
       updateJumpList('');
     });
   }
+
+  document.querySelector('.js-openShortcuts')?.addEventListener('click', () => {
+    shortcutsDialog?.showModal();
+  });
 }
diff --git a/tests/e2e/__image_snapshots__/ci/basic-desktop--404-with-fetch-button-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-desktop--404-with-fetch-button-screenshot-snap.png
index f0f3e7c..45bf610 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-desktop--404-with-fetch-button-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-desktop--404-with-fetch-button-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-desktop--badge-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-desktop--badge-screenshot-snap.png
index 2626485..f38cf2b 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-desktop--badge-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-desktop--badge-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-desktop--error-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-desktop--error-screenshot-snap.png
index 53d1afb..c11b835 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-desktop--error-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-desktop--error-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-desktop--home-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-desktop--home-screenshot-snap.png
index 5fb9fd2..7008c2b 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-desktop--home-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-desktop--home-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-desktop--license-policy-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-desktop--license-policy-screenshot-snap.png
index 7897612..17a907c 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-desktop--license-policy-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-desktop--license-policy-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-desktop--search-help-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-desktop--search-help-screenshot-snap.png
index 39199ef..e3070cd 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-desktop--search-help-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-desktop--search-help-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-desktop--sub-repositories-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-desktop--sub-repositories-screenshot-snap.png
index 43b9a86..df22d54 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-desktop--sub-repositories-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-desktop--sub-repositories-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-mobile--404-with-fetch-button-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-mobile--404-with-fetch-button-screenshot-snap.png
index e44d4a9..77dbd8a 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-mobile--404-with-fetch-button-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-mobile--404-with-fetch-button-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-mobile--badge-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-mobile--badge-screenshot-snap.png
index f31762d..ef3ce76 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-mobile--badge-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-mobile--badge-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-mobile--error-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-mobile--error-screenshot-snap.png
index 001a257..bff7cb1 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-mobile--error-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-mobile--error-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-mobile--home-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-mobile--home-screenshot-snap.png
index 8c7f465..c6a7741 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-mobile--home-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-mobile--home-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-mobile--license-policy-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-mobile--license-policy-screenshot-snap.png
index 3aaebf3..46fceb9 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-mobile--license-policy-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-mobile--license-policy-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-mobile--search-help-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-mobile--search-help-screenshot-snap.png
index d23b795..4d126d5 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-mobile--search-help-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-mobile--search-help-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/basic-mobile--sub-repositories-screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/basic-mobile--sub-repositories-screenshot-snap.png
index 5cc6c27..843f022 100644
--- a/tests/e2e/__image_snapshots__/ci/basic-mobile--sub-repositories-screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/basic-mobile--sub-repositories-screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/search-desktop--no-results-snap.png b/tests/e2e/__image_snapshots__/ci/search-desktop--no-results-snap.png
index d80a21b..aab8fc2 100644
--- a/tests/e2e/__image_snapshots__/ci/search-desktop--no-results-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/search-desktop--no-results-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/search-desktop--screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/search-desktop--screenshot-snap.png
index 0dfcc68..f0867d0 100644
--- a/tests/e2e/__image_snapshots__/ci/search-desktop--screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/search-desktop--screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/search-mobile--no-results-snap.png b/tests/e2e/__image_snapshots__/ci/search-mobile--no-results-snap.png
index 9593eca..e9932fd 100644
--- a/tests/e2e/__image_snapshots__/ci/search-mobile--no-results-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/search-mobile--no-results-snap.png
Binary files differ
diff --git a/tests/e2e/__image_snapshots__/ci/search-mobile--screenshot-snap.png b/tests/e2e/__image_snapshots__/ci/search-mobile--screenshot-snap.png
index 4d6d437..fc0c9d9 100644
--- a/tests/e2e/__image_snapshots__/ci/search-mobile--screenshot-snap.png
+++ b/tests/e2e/__image_snapshots__/ci/search-mobile--screenshot-snap.png
Binary files differ
diff --git a/tests/e2e/__snapshots__/ci/basic.desktop.test.ts.snap b/tests/e2e/__snapshots__/ci/basic.desktop.test.ts.snap
index f70544e..c4f178d 100644
--- a/tests/e2e/__snapshots__/ci/basic.desktop.test.ts.snap
+++ b/tests/e2e/__snapshots__/ci/basic.desktop.test.ts.snap
@@ -189,6 +189,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -399,6 +407,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -593,6 +609,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -804,6 +828,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -1450,6 +1482,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -1695,6 +1735,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -2045,6 +2093,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
diff --git a/tests/e2e/__snapshots__/ci/basic.mobile.test.ts.snap b/tests/e2e/__snapshots__/ci/basic.mobile.test.ts.snap
index 8216a6a..c15c9ac 100644
--- a/tests/e2e/__snapshots__/ci/basic.mobile.test.ts.snap
+++ b/tests/e2e/__snapshots__/ci/basic.mobile.test.ts.snap
@@ -173,6 +173,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -367,6 +375,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -545,6 +561,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -748,6 +772,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -1378,6 +1410,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -1607,6 +1647,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
@@ -1941,6 +1989,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
diff --git a/tests/e2e/__snapshots__/ci/search.desktop.test.ts.snap b/tests/e2e/__snapshots__/ci/search.desktop.test.ts.snap
index 893140c..a0b3004 100644
--- a/tests/e2e/__snapshots__/ci/search.desktop.test.ts.snap
+++ b/tests/e2e/__snapshots__/ci/search.desktop.test.ts.snap
@@ -1534,6 +1534,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },
diff --git a/tests/e2e/__snapshots__/ci/search.mobile.test.ts.snap b/tests/e2e/__snapshots__/ci/search.mobile.test.ts.snap
index 7393b7b..1cfd7ba 100644
--- a/tests/e2e/__snapshots__/ci/search.mobile.test.ts.snap
+++ b/tests/e2e/__snapshots__/ci/search.mobile.test.ts.snap
@@ -1517,6 +1517,14 @@
       "role": "link",
     },
     Object {
+      "name": "Toggle theme",
+      "role": "button",
+    },
+    Object {
+      "name": "Open shorcuts modal",
+      "role": "button",
+    },
+    Object {
       "name": "Google logo",
       "role": "link",
     },