/*

 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.
*/
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(c){var d=0;return function(){return d<c.length?{done:!1,value:c[d++]}:{done:!0}}};$jscomp.arrayIterator=function(c){return{next:$jscomp.arrayIteratorImpl(c)}};$jscomp.makeIterator=function(c){var d="undefined"!=typeof Symbol&&Symbol.iterator&&c[Symbol.iterator];return d?d.call(c):$jscomp.arrayIterator(c)};
(function(c,d){"object"===typeof exports&&"undefined"!==typeof module?module.exports=d():"function"===typeof define&&define.amd?define(d):(c=c||self,c.dialogPolyfill=d())})(this,function(){function c(a){for(;a&&a!==document.body;){var b=window.getComputedStyle(a),e=function(n,l){return!(void 0===b[n]||b[n]===l)};if(1>b.opacity||e("zIndex","auto")||e("transform","none")||e("mixBlendMode","normal")||e("filter","none")||e("perspective","none")||"isolate"===b.isolation||"fixed"===b.position||"touch"===
b.webkitOverflowScrolling)return!0;a=a.parentElement}return!1}function d(a){for(;a;){if("dialog"===a.localName)return a;a=a.parentElement}return null}function h(a){a&&a.blur&&a!==document.body&&a.blur()}function f(a){return a&&a.hasAttribute("method")?"dialog"===a.getAttribute("method").toLowerCase():!1}function m(a){this.dialog_=a;this.openAsModal_=this.replacedStyleTop_=!1;a.hasAttribute("role")||a.setAttribute("role","dialog");a.show=this.show.bind(this);a.showModal=this.showModal.bind(this);a.close=
this.close.bind(this);"returnValue"in a||(a.returnValue="");if("MutationObserver"in window)(new MutationObserver(this.maybeHideModal.bind(this))).observe(a,{attributes:!0,attributeFilter:["open"]});else{var b=!1,e=function(){b?this.downgradeModal():this.maybeHideModal();b=!1}.bind(this),n,l=function(k){k.target===a&&(b|="DOMNodeRemoved"===k.type.substr(0,14),window.clearTimeout(n),n=window.setTimeout(e,0))};["DOMAttrModified","DOMNodeRemoved","DOMNodeRemovedFromDocument"].forEach(function(k){a.addEventListener(k,
l)})}Object.defineProperty(a,"open",{set:this.setOpen.bind(this),get:a.hasAttribute.bind(a,"open")});this.backdrop_=document.createElement("div");this.backdrop_.className="backdrop";this.backdrop_.addEventListener("click",this.backdropClick_.bind(this))}var p=window.CustomEvent;p&&"object"!==typeof p||(p=function(a,b){b=b||{};var e=document.createEvent("CustomEvent");e.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail||null);return e},p.prototype=window.Event.prototype);m.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_),g.dm.removeDialog(this))},setOpen:function(a){a?this.dialog_.hasAttribute("open")||this.dialog_.setAttribute("open",""):(this.dialog_.removeAttribute("open"),
this.maybeHideModal())},backdropClick_:function(a){if(this.dialog_.hasAttribute("tabindex"))this.dialog_.focus();else{var b=document.createElement("div");this.dialog_.insertBefore(b,this.dialog_.firstChild);b.tabIndex=-1;b.focus();this.dialog_.removeChild(b)}b=document.createEvent("MouseEvents");b.initMouseEvent(a.type,a.bubbles,a.cancelable,window,a.detail,a.screenX,a.screenY,a.clientX,a.clientY,a.ctrlKey,a.altKey,a.shiftKey,a.metaKey,a.button,a.relatedTarget);this.dialog_.dispatchEvent(b);a.stopPropagation()},
focus_:function(){var a=this.dialog_.querySelector("[autofocus]:not([disabled])");!a&&0<=this.dialog_.tabIndex&&(a=this.dialog_);a||(a=["button","input","keygen","select","textarea"].map(function(b){return b+":not([disabled])"}),a.push('[tabindex]:not([disabled]):not([tabindex=""])'),a=this.dialog_.querySelector(a.join(", ")));h(document.activeElement);a&&a.focus()},updateZIndex:function(a,b){if(a<b)throw Error("dialogZ should never be < backdropZ");this.dialog_.style.zIndex=a;this.backdrop_.style.zIndex=
b},show:function(){this.dialog_.open||(this.setOpen(!0),this.focus_())},showModal:function(){if(this.dialog_.hasAttribute("open"))throw 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 Error("Failed to execute 'showModal' on dialog: The element is not in a Document.");if(!g.dm.pushDialog(this))throw Error("Failed to execute 'showModal' on dialog: There are too many open modal dialogs.");
c(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;g.needsCentering(this.dialog_)?(g.reposition(this.dialog_),this.replacedStyleTop_=!0):this.replacedStyleTop_=!1;this.dialog_.parentNode.insertBefore(this.backdrop_,this.dialog_.nextSibling);this.focus_()},close:function(a){if(!this.dialog_.hasAttribute("open"))throw Error("Failed to execute 'close' on dialog: The element does not have an 'open' attribute, and therefore cannot be closed.");
this.setOpen(!1);void 0!==a&&(this.dialog_.returnValue=a);a=new p("close",{bubbles:!1,cancelable:!1});if(this.dialog_.onclose instanceof Function)this.dialog_.onclose(a);this.dialog_.dispatchEvent(a)}};var g={reposition:function(a){var b=document.body.scrollTop||document.documentElement.scrollTop;a.style.top=Math.max(b,b+(window.innerHeight-a.offsetHeight)/2)+"px"},isInlinePositionSetByStylesheet:function(a){for(var b=0;b<document.styleSheets.length;++b){var e=document.styleSheets[b],n=null;try{n=
e.cssRules}catch(t){}if(n)for(e=0;e<n.length;++e){var l=n[e],k=null;try{k=document.querySelectorAll(l.selectorText)}catch(t){}var r;if(!(r=!k)){a:{for(r=0;r<k.length;++r)if(k[r]===a){k=!0;break a}k=!1}r=!k}if(!r&&(k=l.style.getPropertyValue("top"),l=l.style.getPropertyValue("bottom"),k&&"auto"!==k||l&&"auto"!==l))return!0}}return!1},needsCentering:function(a){return"absolute"!==window.getComputedStyle(a).position||"auto"!==a.style.top&&""!==a.style.top||"auto"!==a.style.bottom&&""!==a.style.bottom?
!1:!g.isInlinePositionSetByStylesheet(a)},forceRegisterDialog:function(a){(window.HTMLDialogElement||a.showModal)&&console.warn("This browser already supports <dialog>, the polyfill may not work correctly",a);if("dialog"!==a.localName)throw Error("Failed to register dialog: The element is not a dialog.");new m(a)},registerDialog:function(a){a.showModal||g.forceRegisterDialog(a)},DialogManager:function(){this.pendingDialogStack=[];var a=this.checkDOM_.bind(this);this.overlay=document.createElement("div");
this.overlay.className="_dialog_overlay";this.overlay.addEventListener("click",function(b){this.forwardTab_=void 0;b.stopPropagation();a([])}.bind(this));this.handleKey_=this.handleKey_.bind(this);this.handleFocus_=this.handleFocus_.bind(this);this.zIndexLow_=1E5;this.zIndexHigh_=100150;this.forwardTab_=void 0;"MutationObserver"in window&&(this.mo_=new MutationObserver(function(b){var e=[];b.forEach(function(n){for(var l=0,k;k=n.removedNodes[l];++l)k instanceof Element&&("dialog"===k.localName&&e.push(k),
e=e.concat(k.querySelectorAll("dialog")))});e.length&&a(e)}))}};g.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})};g.DialogManager.prototype.unblockDocument=function(){document.documentElement.removeEventListener("focus",this.handleFocus_,!0);document.removeEventListener("keydown",this.handleKey_);this.mo_&&this.mo_.disconnect()};
g.DialogManager.prototype.updateStacking=function(){for(var a=this.zIndexHigh_,b=0,e;e=this.pendingDialogStack[b];++b)e.updateZIndex(--a,--a),0===b&&(this.overlay.style.zIndex=--a);(a=this.pendingDialogStack[0])?(a.dialog.parentNode||document.body).appendChild(this.overlay):this.overlay.parentNode&&this.overlay.parentNode.removeChild(this.overlay)};g.DialogManager.prototype.containedByTopDialog_=function(a){for(;a=d(a);){for(var b=0,e;e=this.pendingDialogStack[b];++b)if(e.dialog===a)return 0===b;
a=a.parentElement}return!1};g.DialogManager.prototype.handleFocus_=function(a){if(!this.containedByTopDialog_(a.target)&&document.activeElement!==document.documentElement&&(a.preventDefault(),a.stopPropagation(),h(a.target),void 0!==this.forwardTab_)){var b=this.pendingDialogStack[0];b.dialog.compareDocumentPosition(a.target)&Node.DOCUMENT_POSITION_PRECEDING&&(this.forwardTab_?b.focus_():a.target!==document.documentElement&&document.documentElement.focus());return!1}};g.DialogManager.prototype.handleKey_=
function(a){this.forwardTab_=void 0;if(27===a.keyCode){a.preventDefault();a.stopPropagation();a=new p("cancel",{bubbles:!1,cancelable:!0});var b=this.pendingDialogStack[0];b&&b.dialog.dispatchEvent(a)&&b.dialog.close()}else 9===a.keyCode&&(this.forwardTab_=!a.shiftKey)};g.DialogManager.prototype.checkDOM_=function(a){this.pendingDialogStack.slice().forEach(function(b){-1!==a.indexOf(b.dialog)?b.downgradeModal():b.maybeHideModal()})};g.DialogManager.prototype.pushDialog=function(a){if(this.pendingDialogStack.length>=
(this.zIndexHigh_-this.zIndexLow_)/2-1)return!1;1===this.pendingDialogStack.unshift(a)&&this.blockDocument();this.updateStacking();return!0};g.DialogManager.prototype.removeDialog=function(a){a=this.pendingDialogStack.indexOf(a);-1!==a&&(this.pendingDialogStack.splice(a,1),0===this.pendingDialogStack.length&&this.unblockDocument(),this.updateStacking())};g.dm=new g.DialogManager;g.formSubmitter=null;g.useValue=null;if(void 0===window.HTMLDialogElement){var q=document.createElement("form");q.setAttribute("method",
"dialog");if("dialog"!==q.method&&(q=Object.getOwnPropertyDescriptor(HTMLFormElement.prototype,"method"))){var u=q.get;q.get=function(){return f(this)?"dialog":u.call(this)};var v=q.set;q.set=function(a){return"string"===typeof a&&"dialog"===a.toLowerCase()?this.setAttribute("method",a):v.call(this,a)};Object.defineProperty(HTMLFormElement.prototype,"method",q)}document.addEventListener("click",function(a){g.formSubmitter=null;g.useValue=null;if(!a.defaultPrevented){var b=a.target;if(b&&f(b.form)){if(!("submit"===
b.type&&-1<["button","input"].indexOf(b.localName))){if("input"!==b.localName||"image"!==b.type)return;g.useValue=a.offsetX+","+a.offsetY}d(b)&&(g.formSubmitter=b)}}},!1);var w=HTMLFormElement.prototype.submit;HTMLFormElement.prototype.submit=function(){if(!f(this))return w.call(this);var a=d(this);a&&a.close()};document.addEventListener("submit",function(a){if(!a.defaultPrevented){var b=a.target;if(f(b)&&(a.preventDefault(),a=d(b))){var e=g.formSubmitter;e&&e.form===b?a.close(g.useValue||e.value):
a.close();g.formSubmitter=null}}},!1)}return g});var jumpDialog=document.querySelector(".JumpDialog"),jumpBody=jumpDialog.querySelector(".JumpDialog-body"),jumpList=jumpDialog.querySelector(".JumpDialog-list"),jumpFilter=jumpDialog.querySelector(".JumpDialog-input"),searchInput=document.querySelector(".js-autoComplete");jumpDialog.showModal||dialogPolyfill.registerDialog(jumpDialog);var jumpListItems;
function collectJumpListItems(){for(var c=[],d=document.querySelector(".Documentation"),h=$jscomp.makeIterator(d.querySelectorAll("[data-kind]")),f=h.next();!f.done;f=h.next())c.push(newJumpListItem(f.value));0==c.length&&(c=collectJumpListItemsFallback(d));d=$jscomp.makeIterator(c);for(h=d.next();!h.done;h=d.next())h.value.link.addEventListener("click",function(){jumpDialog.close()});c.sort(function(m,p){return m.lower.localeCompare(p.lower)});return c}
function collectJumpListItemsFallback(c){var d=[],h={};c=$jscomp.makeIterator(c.querySelectorAll("*[id]"));for(var f=c.next();!f.done;f=c.next()){f=f.value;var m=f.getAttribute("id");!h[m]&&/^[^_][^-]*$/.test(m)&&(h[m]=!0,d.push(newJumpListItem(f)))}return d}
function newJumpListItem(c){var d=document.createElement("a"),h=c.getAttribute("id");d.setAttribute("href","#"+h);d.setAttribute("tabindex","-1");var f=c.getAttribute("data-kind");f||(f=guessKind(c));return{link:d,name:h,kind:f,lower:h.toLowerCase()}}
function guessKind(c){switch(c.getAttribute("class")){case "Documentation-functionHeader":case "Documentation-typeFuncHeader":return"function";case "Documentation-typeHeader":return"type";case "Documentation-typeMethodHeader":return"method";default:switch(c.closest("section").getAttribute("class")){case "Documentation-variables":return"variable";case "Documentation-constants":return"constant";case "Documentation-types":return"field";default:return""}}}var lastFilterValue,activeJumpItem=-1;
function updateJumpList(c){lastFilterValue=c;jumpListItems||(jumpListItems=collectJumpListItems());for(setActiveJumpItem(-1);jumpList.firstChild;)jumpList.firstChild.remove();for(var d=new RegExp(c.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"),"gi"),h=$jscomp.makeIterator(jumpListItems),f=h.next();!f.done;f=h.next()){f=f.value;var m=f.name;if(c&&(m=m.replace(d,function(p){return"<b>"+p+"</b>"}),m==f.name))continue;f.link.innerHTML=m+" <i>"+f.kind+"</i>";jumpList.appendChild(f.link)}jumpBody.scrollTop=
0;0<jumpList.children.length&&setActiveJumpItem(0)}function setActiveJumpItem(c){var d=jumpList.children;0<=activeJumpItem&&d[activeJumpItem].classList.remove("JumpDialog-active");c>=d.length&&(c=d.length-1);if(0<=c){d[c].classList.add("JumpDialog-active");var h=d[c].offsetTop-d[0].offsetTop;d=h+d[c].clientHeight;h<jumpBody.scrollTop?jumpBody.scrollTop=h:d>jumpBody.scrollTop+jumpBody.clientHeight&&(jumpBody.scrollTop=d-jumpBody.clientHeight)}activeJumpItem=c}
function incActiveJumpItem(c){0>activeJumpItem||(c=activeJumpItem+c,0>c&&(c=0),setActiveJumpItem(c))}jumpFilter.addEventListener("keyup",function(c){jumpFilter.value.toUpperCase()!=lastFilterValue.toUpperCase()&&updateJumpList(jumpFilter.value)});jumpFilter.addEventListener("keydown",function(c){switch(c.which){case 38:incActiveJumpItem(-1);c.preventDefault();break;case 40:incActiveJumpItem(1);c.preventDefault();break;case 13:0<=activeJumpItem&&jumpList.children[activeJumpItem].click()}});
var shortcutsDialog=document.querySelector(".ShortcutsDialog");shortcutsDialog.showModal||dialogPolyfill.registerDialog(shortcutsDialog);
document.addEventListener("keypress",function(c){if(!jumpDialog.open&&!shortcutsDialog.open){var d=c.target.tagName;if("INPUT"!=d&&"SELECT"!=d&&"TEXTAREA"!=d&&!(c.target.contentEditable&&"true"==c.target.contentEditable||c.metaKey||c.ctrlKey))switch(String.fromCharCode(c.which)){case "f":case "F":c.preventDefault();jumpFilter.value="";jumpDialog.showModal();updateJumpList("");break;case "?":shortcutsDialog.showModal();break;case "/":c.preventDefault(),searchInput.focus()}}});
