/*!
 * @license
 * Copyright 2019-2020 The Go Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */const c=document.querySelector(".JumpDialog"),a=c==null?void 0:c.querySelector(".JumpDialog-body"),o=c==null?void 0:c.querySelector(".JumpDialog-list"),r=c==null?void 0:c.querySelector(".JumpDialog-input"),L=document.querySelector(".js-documentation");let s;function w(){const t=[];if(!!L){for(const e of L.querySelectorAll("[data-kind]"))t.push(M(e));for(const e of t)e.link.addEventListener("click",function(){c==null||c.close()});return t.sort(function(e,n){return e.lower.localeCompare(n.lower)}),t}}function M(t){var m;const e=document.createElement("a"),n=t.getAttribute("id");e.setAttribute("href","#"+n),e.setAttribute("tabindex","-1"),e.setAttribute("data-gtmc","jump to link");const l=t.getAttribute("data-kind");return{link:e,name:n!=null?n:"",kind:l!=null?l:"",lower:(m=n==null?void 0:n.toLowerCase())!=null?m:""}}let v,f=-1;function T(t){for(v=t,s||(s=w()),k(-1);o==null?void 0:o.firstChild;)o.firstChild.remove();if(t){const e=t.toLowerCase(),n=[],l=[],m=[],p=(i,u,d)=>i.name.substring(0,u)+"<b>"+i.name.substring(u,d)+"</b>"+i.name.substring(d);for(const i of s!=null?s:[]){const u=i.name.toLowerCase();if(u===e)i.link.innerHTML=p(i,0,i.name.length),n.push(i);else if(u.startsWith(e))i.link.innerHTML=p(i,0,t.length),l.push(i);else{const d=u.indexOf(e);d>-1&&(i.link.innerHTML=p(i,d,d+t.length),m.push(i))}}for(const i of n.concat(l).concat(m))o==null||o.appendChild(i.link)}else{if(!s||s.length===0){const e=document.createElement("i");e.innerHTML="There are no symbols on this page.",o==null||o.appendChild(e)}for(const e of s!=null?s:[])e.link.innerHTML=e.name+" <i>"+e.kind+"</i>",o==null||o.appendChild(e.link)}a&&(a.scrollTop=0),(s==null?void 0:s.length)&&o&&o.children.length>0&&k(0)}function k(t){const e=o==null?void 0:o.children;if(!(!e||!a)){if(f>=0&&e[f].classList.remove("JumpDialog-active"),t>=e.length&&(t=e.length-1),t>=0){e[t].classList.add("JumpDialog-active");const n=e[t].offsetTop-e[0].offsetTop,l=n+e[t].clientHeight;n<a.scrollTop?a.scrollTop=n:l>a.scrollTop+a.clientHeight&&(a.scrollTop=l-a.clientHeight)}f=t}}function E(t){if(f<0)return;let e=f+t;e<0&&(e=0),k(e)}r==null||r.addEventListener("keyup",function(){r.value.toUpperCase()!=v.toUpperCase()&&T(r.value)}),r==null||r.addEventListener("keydown",function(t){const e=38,n=40,l=13;switch(t.which){case e:E(-1),t.preventDefault();break;case n:E(1),t.preventDefault();break;case l:f>=0&&o&&(o.children[f].click(),t.preventDefault());break}});const h=document.querySelector(".ShortcutsDialog");document.addEventListener("keypress",function(t){if((c==null?void 0:c.open)||(h==null?void 0:h.open))return;const e=t.target,n=e==null?void 0:e.tagName;if(n=="INPUT"||n=="SELECT"||n=="TEXTAREA"||(e==null?void 0:e.contentEditable)=="true"||t.metaKey||t.ctrlKey)return;switch(String.fromCharCode(t.which)){case"f":case"F":t.preventDefault(),r&&(r.value=""),c==null||c.showModal(),r==null||r.focus(),T("");break;case"?":h==null||h.showModal();break}});const b=document.querySelector(".js-jumpToInput");b&&b.addEventListener("click",()=>{r&&(r.value=""),T("")});
//# sourceMappingURL=jump.js.map
